Git修正錯誤


人非聖賢孰能。所以每個VCS都提供一個功能來修復錯誤,直到Git控制的某一點上。 Git提供了一個功能,可用於撤消對本地儲存庫所做的修改。

假設使用者意外地對本地儲存庫進行了一些更改,然後想要撤消這些更改。 在這種情況下,恢復操作起著重要的作用。

恢復未提交的更改

假設我們不小心修改了本地儲存庫中的一個檔案,此時想復原這些修改。為了處理這種情況,我們可以使用git checkout命令。可以使用此命令來還原檔案的內容。

為了更好的演示,我們首先在 sample/src 目錄下建立一個檔案:string.py ,其程式碼如下所示 -

#!/usr/bin/python3

var1 = 'Hello World!'
var2 = "Python Programming"

print ("var1[0]: ", var1[0])
print ("var2[1:5]: ", var2[1:5]) # 切片加索引

並使用以下命令將此檔案推播到遠端儲存庫 -

$ pwd
/D/worksp/sample

Administrator@MY-PC /D/worksp/sample (master)
$ git add src/

Administrator@MY-PC /D/worksp/sample (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        new file:   src/string.py


Administrator@MY-PC /D/worksp/sample (master)
$ git add src/string.py

Administrator@MY-PC /D/worksp/sample (master)
$ git commit -m "add new file string.py"
[master 44ea8e4] add new file string.py
 1 file changed, 7 insertions(+)
 create mode 100644 src/string.py

Administrator@MY-PC /D/worksp/sample (master)
$ git push origin master
Username for 'http://git.oschina.net': [email protected]
Password for 'http://[email protected]@git.oschina.net':
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (4/4), 443 bytes | 0 bytes/s, done.
Total 4 (delta 0), reused 0 (delta 0)

現在,已經將string.py新增到遠端儲存庫中了。

假設我們不小心/或者有心修改了本地儲存庫中的一個檔案。但現在不想要這些修改的內容了,也就是說想要復原修改。要處理這種情況,那麼可以使用git checkout命令。可以使用此命令來還原檔案的內容。

$ pwd
/D/worksp/sample

Administrator@MY-PC /D/worksp/sample (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/string.py

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@MY-PC /D/worksp/sample (master)
$ git checkout src/string.py

Administrator@MY-PC /D/worksp/sample (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

Administrator@MY-PC /D/worksp/sample (master)
$

此外,還可以使用git checkout命令從本地儲存庫獲取已刪除的檔案。假設我們從本地儲存庫中刪除一個檔案,我們想要恢復這個檔案。那麼可以通過使用git checkout命令來實現這一點。

$ ls -l
total 1
-rw-r--r--    1 Administ Administ       57 Jul  7 05:37 README.md
drwxr-xr-x    1 Administ Administ        0 Jul 10 21:16 src

Administrator@MY-PC /D/worksp/sample (master)
$ cd src/

Administrator@MY-PC /D/worksp/sample/src (master)
$ ls -l
total 1
-rwxr-xr-x    1 Administ Administ      156 Jul 10 21:16 string.py

Administrator@MY-PC /D/worksp/sample/src (master)
$ rm string.py

Administrator@MY-PC /D/worksp/sample/src (master)
$ ls -l
total 0

Administrator@MY-PC /D/worksp/sample/src (master)
$ git status -s
 D string.py

Git在檔案名前顯示字母D, 這表示該檔案已從本地儲存庫中刪除。

$ git checkout string.py

Administrator@MY-PC /D/worksp/sample/src (master)
$ ls -l
total 1
-rwxr-xr-x    1 Administ Administ      156 Jul 10 21:24 string.py

Administrator@MY-PC /D/worksp/sample/src (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

注意:可以在提交操作之前執行這些操作。

刪除分段區域的更改

我們已經看到,當執行新增操作時,檔案將從本地儲存庫移動到暫存區域。 如果使用者意外修改檔案並將其新增到暫存區域,則可以使用git checkout命令恢復其更改。

在Git中,有一個HEAD指標總是指向最新的提交。 如果要從分段區域撤消更改,則可以使用git checkout命令,但是使用checkout命令,必須提供一個附加引數,即HEAD指標。 附加的提交指標引數指示git checkout命令重置工作樹,並刪除分段更改。

讓我們假設從本地儲存庫修改一個檔案。 如果檢視此檔案的狀態,它將顯示該檔案已修改但未新增到暫存區域。

$ pwd
/D/worksp/sample/src

Administrator@MY-PC /D/worksp/sample/src (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   string.py

no changes added to commit (use "git add" and/or "git commit -a")

Administrator@MY-PC /D/worksp/sample/src (master)
$ git add string.py

Git狀態顯示該檔案存在於暫存區域,現在使用git checkout命令恢復該檔案,並檢視還原檔案的狀態。

$ git checkout head -- string.py

Administrator@MY-PC /D/worksp/sample/src (master)
$ git status
On branch master
Your branch is up-to-date with 'origin/master'.

nothing to commit, working directory clean

用Git復位移動頭指標

經過少量更改後,可以決定刪除這些更改。 git reset命令用於復位或恢復更改。 我們可以執行三種不同型別的復位元運算。

下圖顯示了git reset命令的圖示。

git reset命令之前 -

git reset命令之後 -

—soft選項

每個分支都有一個HEAD指標,它指向最新的提交。 如果用--soft選項後跟提交ID的Git reset命令,那麼它將僅重置HEAD指標而不會破壞任何東西。

.git/refs/heads/master檔案儲存HEAD指標的提交ID。 可使用git log -1命令驗證它。

$ pwd
/D/worksp/sample

Administrator@MY-PC /D/worksp/sample (master)
$ cat .git/refs/heads/master
44ea8e47307b47c9a80b44360e09f973e79312b0

現在,檢視最新前兩個的提交ID,最近一次ID將與上述提交ID一致。

$ git log -2
commit 44ea8e47307b47c9a80b44360e09f973e79312b0
Author: maxsu <[email protected]>
Date:   Mon Jul 10 21:09:35 2017 +0800

    add new file string.py

commit 7d8162db36723b8523c56ad658a07808ae7fb64c
Author: minsu <[email protected]>
Date:   Mon Jul 10 17:51:11 2017 -0700

    remove/delete module.py

Administrator@MY-PC /D/worksp/sample (master)
$

下面我們重置HEAD指標。



現在,只需將HEAD指標重新設定一個位置。現在檢視.git/refs/heads/master檔案的內容。

Administrator@MY-PC /D/worksp/sample (master)
$ cat .git/refs/heads/master
7d8162db36723b8523c56ad658a07808ae7fb64c

來自檔案的提交ID已更改,現在通過檢視提交訊息進行驗證。

$ git log -2
commit 7d8162db36723b8523c56ad658a07808ae7fb64c
Author: minsu <[email protected]>
Date:   Mon Jul 10 17:51:11 2017 -0700

    remove/delete module.py

commit 6bdbf8219c60d8da9ad352c23628600faaefbe13
Author: maxsu <[email protected]>
Date:   Mon Jul 10 20:34:28 2017 +0800

    renamed main.py to module.py

mixed選項

使用--mixed選項的Git重置將從尚未提交的暫存區域還原這些更改。它僅從暫存區域恢復更改。對檔案的工作副本進行的實際更改不受影響。 預設Git復位等效於執行git reset - mixed

hard選項

如果使用--hard選項與Git重置命令,它將清除分段區域; 它會將HEAD指標重置為特定提交ID的最新提交,並刪除本地檔案更改。

讓我們檢視提交ID。

Administrator@MY-PC /D/worksp/sample (master)
$ pwd
/D/worksp/sample

Administrator@MY-PC /D/worksp/sample (master)
$ git log -1
commit 7d8162db36723b8523c56ad658a07808ae7fb64c
Author: minsu <[email protected]>
Date:   Mon Jul 10 17:51:11 2017 -0700

    remove/delete module.py

通過在檔案開頭新增單行注釋來修改檔案或者往檔案裡新增其它程式碼。

$ head -2 src/string.py
#!/usr/bin/python3


Administrator@MY-PC /D/worksp/sample (master)
$ git status -s
 M src/string.py

將修改的檔案新增到暫存區域,並使用git status命令進行驗證。

$ git add src/string.py

Administrator@MY-PC /D/worksp/sample (master)
$ git status
On branch master
Your branch and 'origin/master' have diverged,
and have 1 and 1 different commit each, respectively.
  (use "git pull" to merge the remote branch into yours)

Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)

        modified:   src/string.py

Git狀態顯示該檔案存在於暫存區域中。 現在,重置HEAD與--hard選項。

$ git reset --hard 7d8162db36723b8523c56ad658a07808ae7fb64c
HEAD is now at 7d8162d remove/delete module.py

Administrator@MY-PC /D/worksp/sample (master)

git reset命令成功,這將從分段區域還原檔案,並刪除對檔案所做的任何本地更改。

Administrator@MY-PC /D/worksp/sample (master)
$ git status -s

Git狀態顯示該檔案已從暫存區域還原,當前恢復到了刪除 moudle.py 時的版本了。