git reset 命令詳解(二)—— Git 學習筆記 08

ARM的程式設計師敲著詩歌的夢發表於2018-08-22

git reset 命令詳解(二)

上一篇博文git reset 命令詳解(一)講了 git reset 命令的基本原理和用法,這篇博文談一談 git reset 的另一種用法——後面跟一個路徑(或檔案)。

恢復索引中的檔案到某個版本

假設版本庫中是檔案file.txt的V1版本,HEAD、Index和工作目錄都和版本庫一致。這時候修改了file.txt檔案,並把它(V2版本)加入Index。如下圖所示:

這裡寫圖片描述

現在,執行 git reset file.txt (這其實是 git reset --mixed HEAD file.txt 的簡寫形式),它會讓索引看起來像 HEAD, 所以它本質上只是將 file.txt 從 HEAD 複製到索引中。如下圖:

這裡寫圖片描述

仔細對比這兩幅圖,你會發現 git reset file.txt 有 “取消暫存檔案” 的實際效果。它和 git add 所做的事相反。這就是為什麼 git status 命令的輸出會建議執行此命令來取消暫存一個檔案。例如:

$ git add *
$ git status
On branch master
Changes to be committed:
  (use "git reset HEAD <file>..." to unstage)
    renamed:    README.md -> README
    modified:   CONTRIBUTING.md

另外,我們可以不讓 Git 從 HEAD 拉取資料,而是通過具體指定一個提交來拉取該檔案的對應版本。 我們只需執行類似於 git reset eb43bf file.txt 的命令即可。依然用圖來說明:

這裡寫圖片描述

以上是版本庫、Index 和工作目錄的狀態。

現在,執行git reset eb43 file.txt

這裡寫圖片描述

壓縮提交(squashing commit)

假設你有一個專案,第一次提交中增加了檔案 a,第二次提交增加了一個新的檔案 b 並修改了 a,第三次提交再次修改了 a。如下圖:

這裡寫圖片描述

你發現第二次和第三次提交其實是增加了一個軟體功能,把二者壓縮成一次提交更合理。那麼可以這樣做:

首先,執行 git reset --soft HEAD~2 來將 HEAD 分支移動到一箇舊一點的提交上(即你想要保留的最近一次提交):

這裡寫圖片描述

然後,執行 git commit

這裡寫圖片描述

現在你可以檢視可到達的歷史,即將會推送的歷史,現在看起來有個 v1 版 file-a.txt 的提交,接著第二個提交將 file-a.txt 修改成了 v3 版並增加了 file-b.txt。 包含 v2 版本的檔案已經不在歷史中了。




參考資料

《Pro Git》(Scott Chacon, Ben Straub Version 2.1.14, 2018-05-19)

相關文章