← 上一章:【狀況題】修改歷史訊息 下一章:【狀況題】把一個 Commit 拆解成多個 Commit →


【狀況題】把多個 Commit 合併成一個 Commit

有時候 Commit 的太過「瑣碎」,舉個例子來說:

$ git log --oneline
27f6ed6 (HEAD -> master) add dog 2
2bab3e7 add dog 1
ca40fc9 add 2 cats
1de2076 add cat 2
cd82f29 add cat 1
382a2a5 add database settings
bb0c9c2 init commit

cd82f291de2076 這兩個 Commit 都只有各加一個檔案(分別是 cat1.htmlcat2.html),2bab3e727f6ed6 也一樣,都只各加了一個檔案而已。如果想把這幾個 Commit 合併成一個,會讓 Commit 看起來更乾淨一些。同樣可以使用互動模式的 Rebase 來處理:

$ git rebase -i bb0c9c2

接著一樣再次出現 Vim 編輯器視窗,內容如下:

pick 382a2a5 add database settings
pick cd82f29 add cat 1
pick 1de2076 add cat 2
pick ca40fc9 add 2 cats
pick 2bab3e7 add dog 1
pick 27f6ed6 add dog 2

# Rebase bb0c9c2..27f6ed6 onto bb0c9c2 (6 commands)
#
# Commands:
# ...[略]...

這裡我用的指令是 squash,把上面的內容修改成這樣:

pick 382a2a5 add database settings
pick cd82f29 add cat 1
squash 1de2076 add cat 2
squash ca40fc9 add 2 cats
pick 2bab3e7 add dog 1
squash 27f6ed6 add dog 2

注意!

在互動模式的紀錄由上而下是從最舊到最新,跟 git log 指令所呈現的結果是相反的。

上面這樣的修改表示接下來會發生這些事:

  1. 最後一行的 27f6ed6 會跟前一個 Commit 2bab3e7 進行合併,也就是 add dog 1add dog 2 這個 Commit 會合在一起。
  2. 倒數第三號的 ca40fc9 會跟前一個 Commit 1de2076 合併,但因為 1de2076 又會再往前一個 Commit cd82f29 合併,所以整個跟 cat 有關的這三個 Commit 會併成同一個。

存檔並離開 Vim 編輯器後,它會開始進行 Rebase,而在 Squash 的過程中,它還會跳出 Vim 編輯器讓你編輯一下訊息:

squash

我把訊息改成「add all cats」:

squash

同樣的,在另一次的 Squash 也會再編輯一次 Commit 訊息,我把它改成「add all dogs」。整個 Rebase 的訊息如下:

$ git rebase -i bb0c9c2
[detached HEAD fb79104] add all cats
 Date: Sun Aug 20 05:08:25 2017 +0800
 4 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 cat1.html
 create mode 100644 cat2.html
 create mode 100644 cat3.html
 create mode 100644 cat4.html
[detached HEAD 803eeac] add all dogs
 Date: Sun Aug 20 05:09:53 2017 +0800
 2 files changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 dog1.html
 create mode 100644 dog2.html
Successfully rebased and updated refs/heads/master.

這時候的歷史紀錄就變成這樣了:

squash

這樣就把剛剛那些貓貓狗狗的,全部整理成兩個 Commit 了。

使用 SourceTree

使用 SourceTree 在歷史紀錄上的 Commit 上按滑鼠右鍵,選擇「Rebase children of SHA-1 interactively…」,進入互動模式。這時,我先在 add dog 2 這個 Commit 上按滑鼠右鍵並選擇「Squash with previous commit…」:

squash

接著是在 add cat 2 上做一樣的事:

squash

再來是 add 2 cats

squash

注意!

因為這邊是要合併三個 Commit,如果上面這兩個步驟反過來,你會發現沒辦法順利的「Squash」,這時只要按下 Cmd + Z 就可以回到上一步再重來一次。

接著,編輯剛剛「濃縮」的這兩個 Commit 的訊息,這是編輯完成的 Commit 訊息之後的樣子:

squash

全部完成之後,按下右下角的 OK 鈕就會開始進行 Rebase,這樣就可以把多個 Commit 合併成一個了。


← 上一章:【狀況題】修改歷史訊息 下一章:【狀況題】把一個 Commit 拆解成多個 Commit →

Comments