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

2022-07-06 12:05:35

git reset --mixed commit-id命令:回退到指定版本。(mixed:混合的,即:中等回退。)

該命令不僅修改了分支中HEAD指標的位置,還將暫存區中資料也回退到了指定版本。

但是工作區中的版本仍是回退前的版本。

--mixed引數是git reset命令的預設選項。

範例開始:

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

1、檢視本地版本庫紀錄檔。

# 1.使用git log檢視歷史版本記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
bcd2726 (HEAD -> master) 第3次提交,新增內容:readme.txt file v3
b2de20c 第2次提交,新增內容:readme.txt file v2
40212c3 第1次提交,建立readme.txt檔案

# 2.使用git reflog檢視歷史版本記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git reflog
bcd2726 (HEAD -> master) HEAD@{0}: commit: 第3次提交,新增內容:readme.txt file v3
b2de20c HEAD@{1}: commit: 第2次提交,新增內容:readme.txt file v2
40212c3 HEAD@{2}: commit (initial): 第1次提交,建立readme.txt檔案

# 3.檢視readme.txt檔案的內容
L@DESKTOP-T2AI2SU 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.新增資料
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ echo "readme.txt file v4" >> readme.txt

# 2.檢視readme.txt檔案內容
L@DESKTOP-T2AI2SU 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.提交到本地版本庫
L@DESKTOP-T2AI2SU 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 68701fc] 第4次提交,新增內容:readme.txt file v4
 1 file changed, 1 insertion(+)

# 4.現在檢視此時本地版本庫紀錄檔
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
68701fc (HEAD -> master) 第4次提交,新增內容:readme.txt file v4
bcd2726 第3次提交,新增內容:readme.txt file v3
b2de20c 第2次提交,新增內容:readme.txt file v2
40212c3 第1次提交,建立readme.txt檔案

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

# 1.比對工作區與暫存區中檔案的差異
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git diff readme.txt

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

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

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

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

# 回退一個提交版本
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git reset --mixed HEAD^
Unstaged changes after reset:
M       readme.txt

說明:

  • Unstaged changes after reset:意思是回退後,有為被追蹤的檔案。
  • M readme.txt:表示readme.txt檔案修改後,未被追蹤,也就是修改後未新增到暫存區的狀態。

這裡也就說明了,暫存區中readme.txt檔案被回退了。我們還是繼續按步驟往下演示。

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

# 1.比對工作區與暫存區中檔案的差異
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git diff readme.txt
warning: LF will be replaced by CRLF in readme.txt.
The file will have its original line endings in your working directory
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

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

# 3.比對工作區與本地版本庫中檔案的差異
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git diff HEAD readme.txt
warning: LF will be replaced by CRLF in readme.txt.
The file will have its original line endings in your working directory
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檢視歷史版本記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
bcd2726 (HEAD -> master) 第3次提交,新增內容:readme.txt file v3
b2de20c 第2次提交,新增內容:readme.txt file v2
40212c3 第1次提交,建立readme.txt檔案

# 2.使用git reflog檢視歷史版本記錄
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git reflog
bcd2726 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
68701fc HEAD@{1}: commit: 第4次提交,新增內容:readme.txt file v4
bcd2726 (HEAD -> master) HEAD@{2}: commit: 第3次提交,新增內容:readme.txt file v3
b2de20c HEAD@{3}: commit: 第2次提交,新增內容:readme.txt file v2
40212c3 HEAD@{4}: commit (initial): 第1次提交,建立readme.txt檔案

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

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

7、恢復到回退前版本。

上面說了,使用git reset --mixed命令回退,做了兩個操作:

  1. 移動HEAD指標(版本庫的回退)。
  2. 暫存區的內容也回退到HEAD指標指向的版本。

而工作區內容不回退。

我們現在來檢視一下工作目錄中的檔案狀態。

L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   readme.txt

no changes added to commit (use "git add" and/or "git commit -a")

我們可以看到readme.txt檔案是修改未暫存狀態。

所以若要恢復到回退之前的版本,也是兩種方式:

  1. 把工作區的readme.txt檔案新增到暫存區,在commit提交到本地版本庫中。
  2. 使用git reset --mixed 68701fc命令,退回到第四次提交版本。

提示(重要):就本例而言,雖然可以通過先add到暫存區,再commit提交到本地版本庫的方式,就可以恢復回退前的版本。但若回退的版本是很多版本之前的版本,最好不要使用該方式,而是使用版本跳轉命令的方式(也就是第二種方式)。

第一種常規操作,這裡就不演示了。下面演示一下第二種方式:

# 1.檢視可回退的歷史版本
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git reflog
bcd2726 HEAD@{1}: reset: moving to HEAD^
68701fc (HEAD -> master) HEAD@{2}: commit: 第4次提交,新增內容:readme.txt file v4
bcd2726 HEAD@{3}: commit: 第3次提交,新增內容:readme.txt file v3
b2de20c HEAD@{4}: commit: 第2次提交,新增內容:readme.txt file v2
40212c3 HEAD@{5}: commit (initial): 第1次提交,建立readme.txt檔案

# 2.回退到第四次提交
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git reset --mixed 68701fc

# 3.檢視工作目錄中檔案狀態
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git status
On branch master
nothing to commit, working tree clean

# 4.檢視版本歷史
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git log --oneline
68701fc (HEAD -> master) 第4次提交,新增內容:readme.txt file v4
bcd2726 第3次提交,新增內容:readme.txt file v3
b2de20c 第2次提交,新增內容:readme.txt file v2
40212c3 第1次提交,建立readme.txt檔案

# 5.檢視可回退的歷史版本
L@DESKTOP-T2AI2SU MINGW64 /j/git-repository/learngit (master)
$ git reflog
68701fc (HEAD -> master) HEAD@{0}: reset: moving to 68701fc
bcd2726 HEAD@{1}: reset: moving to HEAD^
68701fc (HEAD -> master) HEAD@{2}: commit: 第4次提交,新增內容:readme.txt file v4
bcd2726 HEAD@{3}: commit: 第3次提交,新增內容:readme.txt file v3
b2de20c HEAD@{4}: commit: 第2次提交,新增內容:readme.txt file v2
40212c3 HEAD@{5}: commit (initial): 第1次提交,建立readme.txt檔案

# 6.檢視readme.txt內容
L@DESKTOP-T2AI2SU 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

我們檢視到,readme.txt檔案的內容已經完全恢復。