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