在Git中後悔藥有三種:amend
、revert
、reset
。
git commit --amend
:新的提交覆蓋上一次提交的內容。git revert
:提交一個新的commit
,來複原之前的commit
。git reset
:直接回滾到指定的commit
。--soft
:只回退版本庫,工作區和暫存區的內容不回退。--mixed(預設)
:回退版本庫和暫存區,工作區中的內容不回退。--hard
:工作區,暫存區,版本庫中的內容都回退到指定的提交。(危險的)提示:之前我們把
git reset
命令說完了,git commit --amend
命令我們下一篇文章說。這篇文章來說git revert
命令。
在我們使用Git的操作中,遇到需要回滾程式碼的情況幾乎是難以避免的,而 git revert
命令是一個非常實用的功能,掌握好 git revert
命令的使用是很有必要的。
git revert
命令:是用於「反做」某一個版本,以達到復原該版本的修改的目的。
比如,我們提交了三個版本,突然發現版本二不行(如:有bug
),想要復原版本二,但不想或不需要復原版本三提交,就可以用 git revert
命令來反做版本二,同時生成新的版本四,這個版本四里會保留版本三的東西,但復原了版本二的東西。
但注意:版本二的歷史提交記錄是不會刪除的。
如下圖所示:
提示:注意是
revert命令
是撤回某個改動,不是reset
命令撤回到某個改動。另外,這條命令不會刪除任何commit
記錄,而是會新增一條revert
操作的commit
記錄(會彈出commit message
的編輯視窗)。
現有一個版本庫,其中有4次提交,版本庫的歷史提交記錄如下:
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ git log --oneline
c04b29c (HEAD -> master) 第4次提交,新增內容:revert test v4
fd819dc 第3次提交,新增內容:revert test v3
c71ae3c 第2次提交,新增內容:revert test v2
557f7c3 第1次提交,新增readme.txt檔案
我們發現第三次提交和第四次提交有錯誤,需要復原。
如下圖:
commit-1
和 commit-2
是正常提交,而 commit-3
和 commit-4
是錯誤提交。現在,我們想把 commit-3
和 commit-4
復原掉。而此時,HEAD 指標指向 commit-4
提交(c04b29c
)。我們只需將 HEAD 指標移動到commit-2
提交(c71ae3c
),就可以達到目的。
我們一定會想到之前學過的 git reset
命令。執行命令git reset --hard c71ae3c
,就可以退回到 commit-2
提交。
採用這種方式回退程式碼的弊端顯而易見,那就是會使 HEAD 指標往回移動,從而會失去之後的提交資訊。將來如果突然發現, commit-3
和 commit-4
是多麼絕妙的想法,可它們已經早就消失在歷史的長河裡了(但是通過reflog
也能找回來)。
而且,有些公司明令禁止使用 git reset
命令去回退程式碼,原因與上述一樣。所以,我們需要找到一個命令,既可以回退程式碼,又可以儲存錯誤的提交。這時 git revert
命令就派上用場了。
命令:git revert <commit>
演示:
# 1.復原第四次提交
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ git revert c04b29c
[master d0c8e48] Revert "第5次提交,revert 復原第4次提交"
1 file changed, 1 deletion(-)
# 之後會彈出一個編輯文字方塊,來讓你寫新生成提交的註釋,如下圖。
# 2.檢視版本庫歷史提交記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ git log --oneline
d0c8e48 (HEAD -> master) Revert "第5次提交,revert 復原第4次提交"
c04b29c 第4次提交,新增內容:revert test v4
fd819dc 第3次提交,新增內容:revert test v3
c71ae3c 第2次提交,新增內容:revert test v2
557f7c3 第1次提交,新增readme.txt檔案
# 可以看到第4次提交的commit依然存在。
# 3.檢視readme.txt檔案內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ cat readme.txt
revert test v1
revert test v2
revert test v3
# 可以看到V4 版本內容已經沒有了。
如下圖所示:
這裡需要說明一下:
git revert
命令的作用通過反做建立一個新的版本,這個版本的內容與我們要回退到的目標版本一樣,但是HEAD指標,是指向這個新生成的版本,而不是目標版本。
使用 git revert
命令來實現上述例子的話,我們可以這樣做:先 revert commit-4
,再 revert commit-3
(有多個提交需要回退的話需要由新提交到舊提及哦啊進行 revert)。
我們繼續同樣的操作步驟,把第三次提交也復原掉。
# 1.復原第3次提交
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ git revert fd819dc
[master 30f7626] Revert "第6次提交,revert 復原第3次提交"
1 file changed, 1 deletion(-)
# 2.檢視版本庫歷史提交記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ git log --oneline
30f7626 (HEAD -> master) Revert "第6次提交,revert 復原第3次提交"
d0c8e48 Revert "第5次提交,revert 復原第4次提交"
c04b29c 第4次提交,新增內容:revert test v4
fd819dc 第3次提交,新增內容:revert test v3
c71ae3c 第2次提交,新增內容:revert test v2
557f7c3 第1次提交,新增readme.txt檔案
# 3.檢視readme.txt檔案內容
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/revert_test (master)
$ cat readme.txt
revert test v1
revert test v2
通過上面練習,我們可以得出,git reset
復原和git revert
復原的區別,如下圖所示:
git revert <commit>
命令:
git add
命令新增修改的衝突檔案到暫存區中,在使用 git revert --continue
來繼續操作。git revert --abort
命令來停止移除操作,恢復到執行git revert <commit>
命令之前的狀態。revert
移除的過程中出現衝突,需要把這些衝突解決才可以繼續操作。我們可以使用 git revert --skip
命令來跳過一個commit
的衝突解決。如果後續還有衝突,也同樣如此進行跳過,直到全部衝突解決完成。git revert --skip
命令跳過的commit
,將會在歷史提交記錄中被刪除(reflog
命令還是可以看到的),所以git rebase --skip
這個命令慎用。拓展思路:
git revert HEAD
:復原前一次commit
。git revert HEAD^
:復原前前一次commit
。