本文轉載自阮一峯的博客:如何撤銷 Git 操作?
Git 版本管理時,往往需要撤銷某些操作。本文介紹幾種最主要的情況,給出詳細的解釋。更多的命令可以參考《常用 Git 命令清單》一文。
1.撤銷提交
一種常見的場景是,提交代碼以後,你突然意識到這個提交有問題,應該撤銷掉,這時執行下面的命令就可以了。
$ git revert HEAD
上面命令的原理是,在當前提交後面,新增一次提交,抵消掉上一次提交導致的所有變化。它不會改變過去的歷史,所以是首選方式,沒有任何丟失代碼的風險。
git revert
命令只能抵消上一個提交,如果想抵消多個提交,必須在命令行依次指定這些提交。比如,抵消前兩個提交,要像下面這樣寫。
$ git revert [倒數第一個提交] [倒數第二個提交]
git revert
命令還有兩個參數。
--no-edit:執行時不打開默認編輯器,直接使用 Git 自動生成的提交信息。
--no-commit:只抵消暫存區和工作區的文件變化,不產生新的提交。
2.丟棄提交
如果希望以前的提交在歷史中徹底消失,而不是被抵消掉,可以使用git reset
命令,丟棄掉某個提交之後的所有提交。
$ git reset [last good SHA]
git reset
的原理是,讓最新提交的指針回到以前某個時點,該時點之後的提交都從歷史中消失。
默認情況下,git reset
不改變工作區的文件(但會改變暫存區),--hard
參數可以讓工作區裏面的文件也回到以前的狀態。
$ git reset --hard [last good SHA]
執行git reset
命令之後,如果想找回那些丟棄掉的提交,可以使用git reflog
命令,具體做法參考這裏。不過,這種做法有時效性,時間長了可能找不回來。
3.替換上一次提交
提交以後,發現提交信息寫錯了,這時可以使用git commit
命令的--amend
參數,可以修改上一次的提交信息。
$ git commit --amend -m "Fixes bug #42"
它的原理是產生一個新的提交對象,替換掉上一次提交產生的提交對象。
這時如果暫存區有發生變化的文件,會一起提交到倉庫。所以,--amend
不僅可以修改提交信息,還可以整個把上一次提交替換掉。
4.撤銷工作區的文件修改
如果工作區的某個文件被改亂了,但還沒有提交,可以用git checkout
命令找回本次修改之前的文件。
$ git checkout -- [filename]
它的原理是先找暫存區,如果該文件有暫存的版本,則恢復該版本,否則恢復上一次提交的版本。
注意,工作區的文件變化一旦被撤銷,就無法找回了。
5.從暫存區撤銷文件
如果不小心把一個文件添加到暫存區,可以用下面的命令撤銷。
$ git rm --cached [filename]
上面的命令不影響已經提交的內容。
6.撤銷當前分支的變化
你在當前分支上做了幾次提交,突然發現放錯了分支,這幾個提交本應該放到另一個分支。
# 新建一個 feature 分支,指向當前最新的提交
# 注意,這時依然停留在當前分支
$ git branch feature
# 切換到這幾次提交之前的狀態
$ git reset --hard [當前分支此前的最後一次提交]
# 切換到 feature 分支
$ git checkout feature
上面的操作等於是撤銷當前分支的變化,將這些變化放到一個新建的分支。