← 上一章:【狀況題】把多個 Commit 合併成一個 Commit 下一章:【狀況題】想要在某些 Commit 之間再加新的 Commit →


【狀況題】把一個 Commit 拆解成多個 Commit

跟上個章節「【狀況題】把多個 Commit 合併成一個 Commit」相反,有時候覺得單次 Commit 的檔案太多了,可能會想把它拆得細一點,同樣也可使用互動模式的 Rebase 來操作。這是目前的歷史紀錄:

$ 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

ca40fc9 這個 Commit 一口氣增加了兩個檔案,我想把它拆成兩個 Commit,每個 Commit 分別都只有一個檔案就好。起手式跟上個章節一樣:

$ git rebase -i bb0c9c2

一樣跳出一個 Vim 編輯器。這次,我把我要拆的那個 Commit 的 pick 改成 edit

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

Rebase 在執行到 ca40fc9 這個 Commit 的時候就會停下來:

$ git rebase -i bb0c9c2
Stopped at ca40fc9...  add 2 cats
You can amend the commit now, with

  git commit --amend

Once you are satisfied with your changes, run

  git rebase --continue

看目前的狀態的話會像這樣:

split commit

這時,因為我們要把目前這個 Commit 拆成兩個 Commit,還記得怎麼拆 Commit 嗎?沒錯,就是使用 Reset 指令:

$ git reset HEAD^

如果忘記,請回「【狀況題】剛才的 Commit 後悔了,想要拆掉重做…」章節復習一下。看一下目前的狀態:

$ git status
interactive rebase in progress; onto bb0c9c2
Last commands done (4 commands done):
   pick 1de2076 add cat 2
   edit ca40fc9 add 2 cats
  (see more in file .git/rebase-merge/done)
Next commands to do (2 remaining commands):
   pick 2bab3e7 add dog 1
   pick 27f6ed6 add dog 2
  (use "git rebase --edit-todo" to view and edit)
You are currently editing a commit while rebasing branch 'master' on 'bb0c9c2'.
  (use "git commit --amend" to amend the current commit)
  (use "git rebase --continue" once you are satisfied with your changes)

Untracked files:
  (use "git add <file>..." to include in what will be committed)

	cat3.html
	cat4.html

nothing added to commit but untracked files present (use "git add" to track)

可以看到 cat3.htmlcat4.html 都被拆出來放在工作目錄並且是處於 Untracked 狀態。那,還記得怎麼 Commit 檔案嗎?就是用 add + commit 二段式指令:

$ git add cat3.html

把檔案加到暫存區,接下來進行 Commit:

$ git commit -m "add cat 3"
[detached HEAD 8e79d0e] add cat 3
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 cat3.html

還有另一個檔案,依樣畫葫蘆:

$ git add cat4.html
$ git commit -m "add cat 4"
[detached HEAD 06ee3f6] add cat 4
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 cat4.html

同樣的,如果忘記怎麼 Commit 檔案,請再參考「把檔案交給 Git 控管」章節說明。

這樣就把剛剛那個 Commit 拆成兩個 Commit 了。但別忘了現在還是處於 Rebase 狀態,所以要讓 Rebase 繼續跑完喔:

$ git rebase --continue
Successfully rebased and updated refs/heads/master.

看一下現在的歷史紀錄:

split commit

原來的 add 2 cats 已經被拆成 add cat 3add cat 4 了,而且各別都只有一個檔案囉。

使用 SourceTree

這個使用 SourceTree 就沒有方便的介面可以處理了。一樣先叫出互動模式的 Rebase 視窗,然後在要拆的那個 Commit 上打勾:

split commit

打勾就是代表待會在這個 Commit 要停下來編輯的意思。按下右下角 OK 鈕便會開始執行 Rebase 指令,接著你會看到這個畫面:

split commit

HEAD 的確停在 add 2 cats 那個 Commit 了。接下來呢.. 因為 SourceTree 似乎沒有提供可以做這件事情的介面,所以,就乖乖打開終端機,開始上面那些動作吧 :)

喔,忘了說,如果做完的話,在 SourceTree 的功能選單→「Action」→「Continue Rebase」可以繼續完成剩下的 Rebase 指令:

split commit

git rebase --continue 指令是一樣的功效。


← 上一章:【狀況題】把多個 Commit 合併成一個 Commit 下一章:【狀況題】想要在某些 Commit 之間再加新的 Commit →

Comments