IDEA (任意 JetBrains IDE)拆分先前 commit

AaronLin發表於2024-03-27

最近在合併上游程式碼,遇到了一個問題:某個 commit 雜糅了幾個不同的特性修改,這可能會導致 rebase 上游程式碼時需要再對該 commit 進行額外的程式碼衝突處理

解決方法:合併上游分支前,拆分雜糅的 commit,並將其中不同的特性修改合併(Squash)回相關的 commit。可以直接透過命令列進行操作,可以參考:Break a previous commit into multiple commits。也可以透過 JetBrains 家內建的 Git 進行操作,下面會介紹 IDEA 圖形化操作的方法

非先前 commit 的拆分

對於剛提交的 commit,要拆分多個 commit 是非常容易的,因為我們只要 soft reset commit,將 commit 內容撤銷回至 暫存區,就可以隨意提交 commit

如果對於 soft reset 不太瞭解,可以參考我之前的部落格:Git 中的回退操作:reset 和 revert

先前 commit 的拆分

先前 commit 指的是:在目標 commit 後已經有了若干個 commit。它無法直接透過 soft reset 進行拆分,因為這樣會丟失後續的 commit,如下圖,我們需要拆分 B commit,我們就無法直接使用 soft reset ,因為這樣會丟失 CD commit 的修改

所以我們需要使用 rebase,具體步驟:

  1. 在 互動式 (interactive) rebase 中將 B 標記為 edit,這時 B 後面的 commit 會被暫時隱藏起來
  2. 使用 soft resetB 撤銷回 暫存區
  3. B 的修改內容分多個 commit 提交 B1B2
  4. 使用 rebase 的 continue 將剛才隱藏的 CD 恢復回來

例項準備

演示使用 IDEA,其實 JetBrains 家的使用邏輯差不多,示例倉庫使用:Learn Go with Tests

git clone git@github.com:quii/learn-go-with-tests.git

需要用到 Rebase,IDEA 預設保護主分支,改寫 commit 記錄的功能會被禁用

需要先取消分支保護,移除 Protected branches 中的 master;main

假設我們需要將下面 commit 拆分為兩個:

1. 啟動 Rebase 並標記目標 commit 為 edit

點選 Interactively Rebase from Here...

選擇需要拆分的 commit,右鍵選擇 Stop to Edit,然後再點選 Start Rebasing

這時有右下角會提示您正在處於 Rebase 狀態
選擇框可以選擇 Continue 即繼續 Rebase,Abort 則會退出 Rebase

commit 列表也會顯示感嘆號

2. 使用 soft reset 將 commit 撤銷回 暫存區

我們需要先 soft reset 到目標 commit 的上一個 commit
選擇上一個 commit,右鍵選擇:Reset Current Branch to Here...

選擇 Soft,這樣目標 commit 的修改就會退回到暫存區

3. 將暫存區改動分為若干個 commit 提交

這個時候我們就可以繼續分開提交兩次 commit

檢視 log,兩條 commit 被成功提交

4. 使用 rebase 的 continue 恢復剩下的 commit

這時候我們需要繼續 Rebase,將剩下的 commit 還原回去:點選右下角分分支按鈕,選擇 Continue Rebase

完成 Rebase 後,剩餘的 commit 就會被追加到我們新提交的 commit 後面,至此我們就完成了先前 commit 的拆分

Rebase edit 的擴充

因為這裡的案例只是拆分 commit,沒有對 commit 進行修改,如果是修改的話,修改完成後需要使用 git add 將檔案標記為已修改,才能使用 rebase 的 continue,這樣該 commit 就會被修改。後續的 commit 有可能與本次的改動產生衝突,需要手動處理衝突

參考資料

Break a previous commit into multiple commits

相關文章