【學了就忘】Git後悔藥 — 37.revert撤銷(一)

1、Git的三種後悔藥

在Git中後悔藥有三種:amendrevertreset

  • git commit --amend:新的提交覆蓋上一次提交的內容。

  • git revert:提交一個新的commit,來撤銷之前的commit。

  • git reset:直接回滾到指定的commit。

    --soft:只回退版本庫,工作區和暫存區的內容不回退。

    --mixed(默認):回退版本庫和暫存區,工作區中的內容不回退。

    --hard:工作區,暫存區,版本庫中的內容都回退到指定的提交。(危險的)

提示:之前我們把git reset命令說完了,git commit --amend命令我們下一篇文章說。這篇文章來說git revert命令。

2、revert命令原理

在我們使用Git的操作中,遇到需要回滾代碼的情況幾乎是難以避免的,而 git revert 命令是一個非常實用的功能,掌握好 git revert 命令的使用是很有必要的。

git revert命令:是用於“反做”某一個版本,以達到撤銷該版本的修改的目的。

比如,我們提交了三個版本,突然發現版本二不行(如:有bug),想要撤銷版本二,但不想或不需要撤銷版本三提交,就可以用 git revert 命令來反做版本二,同時生成新的版本四,這個版本四里會保留版本三的東西,但撤銷了版本二的東西。

但注意:版本二的歷史提交記錄是不會刪除的。

如下圖所示:

提示:注意是revert命令撤回某個改動,不是reset命令撤回到某個改動。另外,這條命令不會刪除任何commit記錄,而是會新增一條Revert操作的commit記錄(會彈出commit message的編輯窗口)。

3、revert命令的使用

現有一個版本庫,其中有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文件

我們發現第三次提交和第四次提交有錯誤,需要撤銷。

如下圖:


(1)移除某次提交的修改

commit-1commit-2 是正常提交,而 commit-3commit-4 是錯誤提交。現在,我們想把 commit-3commit-4 撤銷掉。而此時,HEAD 指針指向 commit-4 提交(c04b29c)。我們只需將 HEAD 指針移動到commit-2 提交(c71ae3c),就可以達到目的。

我們一定會想到之前學過的 git reset 命令。執行命令git reset --hard c71ae3c,就可以退回到 commit-2 提交。

採用這種方式回退代碼的弊端顯而易見,那就是會使 HEAD 指針往回移動,從而會失去之後的提交信息。將來如果突然發現, commit-3commit-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撤銷的區別,如下圖所示:

(2)revert命令說明

git revert <commit>命令:

  1. 這個命令會生成一個新的提交記錄,新的提交記錄就是把需要移除的提交撤銷掉,所生成的新提交。

  2. 如果工作區或暫存區還有修改未提交,那麼會提示需要先提交或存儲起來這些文件。

  3. 如果在移除的過程中發生了衝突,可以在解決了衝突後,使用 git add 命令添加修改的衝突文件到暫存區中,在使用 git revert --continue 來繼續操作。

    如果不想繼續操作,當然也可以使用 git revert --abort 命令來停止移除操作,恢復到執行git revert <commit>命令之前的狀態。

  4. 如果revert移除的過程中出現衝突,需要把這些衝突解決纔可以繼續操作。我們可以使用 git revert --skip 命令來跳過一個commit的衝突解決。如果後續還有衝突,也同樣如此進行跳過,直到全部衝突解決完成。

    但是使用git revert --skip 命令跳過的commit,將會在歷史提交記錄中被刪除(reflog命令還是可以看到的),所以git rebase --skip 這個命令慎用。

拓展思路:

  • git revert HEAD:撤銷前一次commit。
  • git revert HEAD^:撤銷前前一次 commit。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章