『現學現忘』Git後悔葯 — 31、reset版本回退命令總結
- 2022 年 7 月 8 日
- 筆記
- 高級測試技能 - Git基礎
在Git中進行版本回退需要使用git reset命令。
以前面文章中的示例為例,當我準備在V4版本,回退到V3版本的時候,分支中的提交和工作目錄中文件的狀態,如下圖所示:

我們分別執行了三種回退方式:
git reset --soft HEAD^:溫柔的回退。git reset --mixed HEAD^:中等回退。git reset --hard HEAD^:強硬的回退。
(我們從英文中就可以看出,一個比一個回退的多。)
下面我們一一進行總結。
1、--soft回退說明
當我在V4版本的時候,執行git reset --soft HEAD^命令回退到V3版本。
Git中發生的變化如下圖所示:

依據上圖,理解一下發生的事情:本質上就發生了,把HEAD指針指向了V3版本。而工作區和暫存區中的readme.txt文件是沒有做任何變動的。
所以你查看本地版本庫中的readme.txt文件是V3版本,工作區和暫存區中的readme.txt文件是V4版本。
就等於回滾到了git commit之前的狀態。
(我前面文章中有詳細的演示)
拓展:
當我繼續修改readme.txt文件之後,再次提交,會在V3版本之上在創建一個新的commit提交,並移動HEAD指針指向的分支來使其指向該commit提交,這樣依次提交下去,如下圖所示:

如果我們使用git log命令查看本地版本庫的歷史提交資訊的時候,就不會出現V4版本提交的資訊。會是V1、V2、V3、V5。(我們從前面文章中已經演示了)
但是V4版本是不會在Git中刪除的,會永遠的存儲在Git的本地版本庫中。我們可以使用git reflog命令,可以查看該V4版本的提交資訊。
提示:只要是本地版本庫中
HEAD有過的變化,那麼git reflog命令就能夠顯示出來。
(關於這點,下面同理,所以下面就不說了。)
2、--mixed回退說明
當我在V4版本的時候,執行git reset --mixed HEAD^命令回退到V3版本。
Git中發生的變化,如下圖所示:

理解一下發生的事情,我們可以看到上圖中,完成了兩步操作:
- 把HEAD指針指向了
V3版本(也就是版本庫回退了)。 - 把暫存區中的
readme.txt文件也回退到了V3版本。
而只有工作區中的readme.txt文件內容沒有變化。
這說明git reset --mixed命令比git reset --soft命令,多回退了暫存區中的內容。
就等於回滾到了git commit和git add之前的狀態。
(我前面文章中有詳細的演示)
提示:因為
--mixed參數是git reset命令的默認選項,也就是不寫任何參數就默認使用--mixed參數。即git reset HEAD^等同於git reset --mixed HEAD^命令
3、--hard回退說明
當我在V4版本的時候,執行git reset --hard HEAD^命令回退到V3版本。
Git中發生的變化,如下圖所示:

理解一下發生的事情,我們可以看到上圖中,完成了三步操作:
- 把HEAD指針指向了
V3版本(也就是版本庫回退了)。 - 把暫存區中的
readme.txt文件也回退到了V3版本。 - 把工作區中
readme.txt文件的修改也復原了。
所以執行完git reset --hard HEAD^命令,是完全回退一個版本。
此時工作區、暫存區、本地版本庫中的文件狀態都是一致的,都是V3版本。
就等於回滾了一個「編輯文件,添加到暫存區,提交版本庫」的整個流程。
(我前面文章中有詳細的演示)
4、總結
必須注意:
--hard參數是git reset命令唯一的危險用法,是能夠使Git會真正地銷毀數據的僅有的幾個操作之一。
其他任何形式的git reset操作都可以輕鬆撤消,但是--hard選項不能,因為它強制覆蓋了工作目錄中的文件。
在這種特殊情況下,我們的Git資料庫中的一個提交內,還留有該文件的V4版本,我們可以通過git reflog來找回它。但是若該文件還未提交,Git仍會覆蓋它從而導致無法恢復。

