1. 程式人生 > >Git——寫錯的不是最新的提交,而是倒數第二個?

Git——寫錯的不是最新的提交,而是倒數第二個?

寫錯的不是最新的提交,而是倒數第二個?

commit --amend 可以修復最新 commit 的錯誤,但如果是倒數第二個 commit 寫錯了,怎麼辦?

 

rebase -i:互動式 rebase

如果不是最新的 commit 寫錯,就不能用 commit --amend 來修復了,而是要用 rebase 。不過需 要給 rebase 也加一個引數: -i

 

rebase -irebase --interactive 的縮寫形式,意為「互動式 rebase」。

 

所謂「互動式 rebase」,就是在 rebase 的操作執行之前,你可以指定要 rebase

commit 鏈 中的每一個 commit 是否需要進一步修改。

那麼你就可以利用這個特點,進行一次「原地 rebase」。

 

例如你是在寫錯了 commit 之後,又提交了一次才發現之前寫錯了:

git log

 

開啟互動式 rebase 過程

現在再用 commit --amend 已經晚了,但可以用 rebase -i

git rebase -i HEAD^^

 

說明:

在 Git 中,有兩個「偏移符號」: ^~

^ 的用法:在 commit 的後面加一個或多個 ^ 號,可以把 commit

往回偏移,偏移的數量 是 ^ 的數量。例如: master^ 表示 master 指向的 commit 之前的那個 commitHEAD^^ 表示 HEAD 所指向的 commit 往前數兩個 commit

~ 的用法:在 commit 的後面加上 ~ 號和一個數,可以把 commit 往回偏移,偏移的數量 是 ~ 號後面的數。例如: HEAD~5 表示 HEAD 指向的 commit 往前數 5 個 commit

 

上面這行程式碼表示,把當前 commitHEAD 所指向的 commitrebaseHEAD 之前 2 個的 commit 上:

 

如果沒有 -i 引數的話,這種「原地 rebase」相當於空操作,會直接結束。而在加了 -i 後,就會 跳到一個新的介面:

 

編輯介面:選擇 commit 和對應的操作

這個編輯介面的最頂部,列出了將要「被 rebase」的所有 commit s,也就是倒數第二個 commit 「增加常見笑聲集合」和最新的 commit 「增加常見哭聲集合」。需要注意,這個排列是正序的,舊 的 commit 會排在上面,新的排在下面。

 

這兩行指示了兩個資訊:

  1. 需要處理哪些 commit s;
  2. 怎麼處理它們。

 

你需要修改這兩行的內容來指定你需要的操作。每個 commit 預設的操作都是 pick (從圖中也可以看出),表示「直接應用這個 commit 」。所以如果你現在直接退出編輯介面,那麼結果仍然是空 操作。

 

但你的目標是修改倒數第二個 commit ,也就是上面的那個「增加常見笑聲集合」,所以你需要把它的操作指令從 pick 改成 editedit 的意思是「應用這個 commit,然後停下來等待繼續修正」。其他的操作指令,在這個介面里都已經列舉了出來(下面的 "Commands…" 部分文字),你可以自己研究一下。

 

pick 修改成 edit 後,就可以退出編輯介面了:

 

上圖的提示資訊說明, rebase 過程已經停在了第二個 commit 的位置,那麼現在你就可以去修改你想修改的內容了。

 

修改寫錯的 commit

修改完成之後,和上節里的方法一樣,用 commit --amend 來把修正應用到當前最新的 commit

git add 笑聲
git commit --amend

 

繼續 rebase 過程

在修復完成之後,就可以用 rebase --continue 來繼續 rebase 過程,把後面的 commit 直接應用上去。 

git rebase --continue

 

然後,這次互動式 rebase 的過程就完美結束了,你的那個倒數第二個寫錯的 commit 就也被修正 了:

 

實質上,互動式 rebase 並不是必須應用在「原地 rebase」上來修改寫錯的 commit ,這隻不過是 它最常見的用法。你同樣也可以把它用在分叉的 commit 上,不過這個你就可以自己去研究一下了。

 

小結

這節介紹了互動式 rebase ,它可以在 rebase 開始之前指定一些額外操作。互動式 rebase 最常用的場景是修改寫錯的 commit ,但也可以用作其他用途。它的大致用法:

  1. 使用方式是 git rebase -i 目標commit
  2. 在編輯介面中指定需要操作的 commit s 以及操作型別;
  3. 操作完成之後用 git rebase --continue 來繼續 rebase 過程。