『現學現忘』Git後悔藥 — 28、版本回退git reset --soft命令說明

繁華似錦Fighting 發表於 2022-07-05
Git

git reset --soft commit-id命令:回退到指定版本。(soft:柔軟的)

該命令僅僅修改分支中的HEAD指標的位置,不會改變工作區與暫存區中的檔案的版本。

實現上是隻做了一件事情,就是移動HEAD指標的指向,指向了指定的提交版本。

示例開始:

首先在版本庫中的readme.txt檔案中新增一行內容,並提交該內容。我們的目的就是要再回退到該版本。

1、檢視本地版本庫日誌。

# 1.使用git log檢視歷史版本記錄
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
f4da0ae (HEAD -> master) 第3次提交,新增內容:readme.txt file v3
05f5ff9 第2次提交,新增內容:readme.txt file v2
75b4466 第1次提交,建立readme.txt檔案

# 2.使用git reflog檢視歷史版本記錄
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git reflog
f4da0ae (HEAD -> master) [email protected]{0}: commit: 第3次提交,新增內容:readme.txt file v3
05f5ff9 [email protected]{1}: commit: 第2次提交,新增內容:readme.txt file v2
75b4466 [email protected]{2}: commit (initial): 第1次提交,建立readme.txt檔案

# 3.檢視readme.txt檔案的內容
[email protected] MINGW64 /j/git-repository/learngit (master)
$ cat readme.txt
readme.txt file v1
readme.txt file v2
readme.txt file v3

2、向readme.txt檔案中新增一行資料,並提交到本地版本庫。

# 1.新增資料
[email protected] MINGW64 /j/git-repository/learngit (master)
$ echo "readme.txt file v4" >> readme.txt

# 2.檢視readme.txt檔案內容
[email protected] MINGW64 /j/git-repository/learngit (master)
$ cat readme.txt
readme.txt file v1
readme.txt file v2
readme.txt file v3
readme.txt file v4

# 3.提交到本地版本庫
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git commit -a -m '第4次提交,新增內容:readme.txt file v4'
warning: LF will be replaced by CRLF in readme.txt.
The file will have its original line endings in your working directory
[master 2c4401f] 第4次提交,新增內容:readme.txt file v4
 1 file changed, 1 insertion(+)

# 4.現在檢視此時本地版本庫日誌
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
2c4401f (HEAD -> master) 第4次提交,新增內容:readme.txt file v4
f4da0ae 第3次提交,新增內容:readme.txt file v3
05f5ff9 第2次提交,新增內容:readme.txt file v2
75b4466 第1次提交,建立readme.txt檔案

3、現在比對工作區與暫存區、暫存區與本地版本庫的差異。

# 1.比對工作區與暫存區中檔案的差異
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git diff readme.txt

# 2.比對暫存區與本地版本庫中檔案的差異
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git diff --cached readme.txt

我們可以看到此時,工作區、暫存區與本地版本庫中的readme.txt檔案狀態無差異。

4、開始回退操作,退回到V3版本。

使用git reset --soft HEAD^命令,退回到前一個版本。

# 1.回退一個提交版本
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git reset --soft HEAD^

5、回退後,對比工作區、暫存區與本地庫中版本中檔案的差異。

# 1.比對工作區與暫存區中檔案的差異
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git diff readme.txt

# 2.比對暫存區與本地版本庫中檔案的差異
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git diff --cached readme.txt
diff --git a/readme.txt b/readme.txt
index 1e6534a..47b238c 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,3 +1,4 @@
 readme.txt file v1
 readme.txt file v2
 readme.txt file v3
+readme.txt file v4

# 3.比對工作區與本地版本庫中檔案的差異
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git diff HEAD readme.txt
diff --git a/readme.txt b/readme.txt
index 1e6534a..47b238c 100644
--- a/readme.txt
+++ b/readme.txt
@@ -1,3 +1,4 @@
 readme.txt file v1
 readme.txt file v2
 readme.txt file v3
+readme.txt file v4

回退後,我們再次對比了工作區、暫存區與本地庫中版本中檔案的差異:

  • 發現工作區與暫存區內容沒有差異。
  • 暫存區與本地庫中的版本出現了差異。
  • 工作區與本地庫中的版本出現了差異。

說明:工作區和暫存區中的內容沒有回退,但是本地庫中的內容回退到了之前的版本。(重要)

6、檢視本地版本庫的提交日誌資訊。

# 1.使用git log檢視歷史版本記錄
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
f4da0ae (HEAD -> master) 第3次提交,新增內容:readme.txt file v3
05f5ff9 第2次提交,新增內容:readme.txt file v2
75b4466 第1次提交,建立readme.txt檔案

# 2.使用git reflog檢視歷史版本記錄
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git reflog
f4da0ae (HEAD -> master) [email protected]{0}: reset: moving to HEAD^
2c4401f [email protected]{1}: commit: 第4次提交,新增內容:readme.txt file v4
f4da0ae (HEAD -> master) [email protected]{2}: commit: 第3次提交,新增內容:readme.txt file v3
05f5ff9 [email protected]{3}: commit: 第2次提交,新增內容:readme.txt file v2
75b4466 [email protected]{4}: commit (initial): 第1次提交,建立readme.txt檔案

從上我們可以看到:(重點)

  • 使用git log命令檢視歷史版本記錄,發現已經看不到第4次提交了。
  • 使用git reflog命令檢視歷史版本記錄,第四次提交這個版本仍然存在的。

7、恢復到回退前版本。

因為前面說了,git reset --soft命令回退,只是移動HEAD指標,也就是本地版本庫進行退回,而工作區和暫存區的內容都不回退。

所以若要恢復到回退之前的版本,可以直接將暫存區中的資料commit提交到本地版本庫即可。

# 1.檢視工作目錄中檔案的狀態
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        modified:   readme.txt
# 我們可以看到readme.txt檔案是修改已暫存狀態,提交即可。
# 即當前的Git狀態為暫存區中的版本尚未提交時的狀態。

# 2.提交操作
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git commit -m '第5次提交,append v4 again!'
[master 4399da4] 第5次提交,append v4 again!
 1 file changed, 1 insertion(+)

# 3.檢視工作目錄中檔案狀態
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
nothing to commit, working tree clean
 
# 4.使用git log檢視歷史版本記錄
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
4399da4 (HEAD -> master) 第5次提交,append v4 again!
f4da0ae 第3次提交,新增內容:readme.txt file v3
05f5ff9 第2次提交,新增內容:readme.txt file v2
75b4466 第1次提交,建立readme.txt檔案
# 已經看不到第四次提交了。所以git log命令是看不到全部歷史版本的。

# 5.使用git reflog檢視歷史版本記錄
[email protected] MINGW64 /j/git-repository/learngit (master)
$ git reflog
4399da4 (HEAD -> master) [email protected]{0}: commit: 第5次提交,append v4 again!
f4da0ae [email protected]{1}: reset: moving to HEAD^
2c4401f [email protected]{2}: commit: 第4次提交,新增內容:readme.txt file v4
f4da0ae [email protected]{3}: commit: 第3次提交,新增內容:readme.txt file v3
05f5ff9 [email protected]{4}: commit: 第2次提交,新增內容:readme.txt file v2
75b4466 [email protected]{5}: commit (initial): 第1次提交,建立readme.txt檔案
# 使用git reflog命令,可以看到全部的歷史版本記錄。

提示:我們可以通過git reset --soft命令,回退到第4次提交。

執行命令:$ git reset --soft 2c4401f

也會生成一個新的commit提交,日誌資訊如下:

2c4401f (HEAD -> master) [email protected]{0}: reset: moving to 2c4401f

看到最前的的2c4401f和第四次提交的commit一致,說明已經退回到第四次提交了。