Git 2.54 and 2.55: Exploring the Experimental git history Command

Git 2.54 and 2.55: Exploring the Experimental git history Command

git history 指令在 Git 2.54 與 2.55 版本中推出,提供了一種簡化且具原子性的方式來修改舊的提交(commit),而無需像 git rebase -i 那樣進行手動操作。透過自動化後代分支的 rebase,它將類似於 Jujutsu (jj) 等其他版本控制系統中的高階歷史管理功能,直接引入了 Git 核心發行版中。

Atomic History Modification with git history

git history 的設計是原子性的:它要麼完全成功,要麼什麼都不做。為了防止工作樹(working tree)處於損壞或衝突的狀態,該指令會拒絕任何會產生合併衝突(merge conflict)的操作。這與標準的互動式 rebase 有顯著不同,後者可能會暫停以進行手動衝突解決。

git history fixup

git history fixup <commit> 允許使用者將暫存(staged)的變更併入先前的提交。它的功能類似於 git commit --fixup 與 autosquash rebase 的組合,但具有更廣泛的分支更新範圍。

雖然 git rebase --update-refs 僅移動活動 rebase 範圍內的引用(references),但 git history fixup 會識別並重寫所有從目標提交所衍生的本地分支。這確保了所有相關的功能分支都能與修復保持同步。

Limitations:

  • 它在存在合併提交(merge commits)的情況下無法運作。
  • 它無法處理會導致衝突的操作。

git history reword

git history reword <commit> 會更新特定提交的提交訊息(commit message)。它會開啟使用者的編輯器來編輯訊息,儲存變更後,再於其上方重建剩餘的提交堆疊(commit stack)。

由於此操作僅修改提交訊息而非檔案內容,因此它不會觸及索引(index)或工作樹。這允許使用者在不干擾目前工作的狀況下,重寫目前未檢出(checked out)的分支上的提交。

git history split

git history split <commit> 會將單個提交拆分為兩個獨立的提交。此過程是互動式的,使用逐塊(hunk-by-hunk)提示(類似於 git add -p)讓使用者選擇哪些變更屬於第一個提交,哪些屬於第二個提交。

Comparison with git rebase -i and Jujutsu (jj)

git history 將互動式 rebase 最常見的幾種使用案例簡化為低摩擦、單一用途的指令。然而,它並非其他系統中更強大工具的完全替代品。

Feature git history git rebase -i Jujutsu (jj)
Atomic Operations Yes (fails if conflict) No (pauses for resolution) Yes (conflicts are first-class)
Auto-update Descendants Yes (all local branches) Limited (--update-refs) Native
Working Tree Impact Minimal (for reword/split) High (rewrites tree) Working copy is a commit
Complexity Low (single commands) High (manual list editing) Medium (new mental model)

Community Insights and Practical Considerations

社群討論強調了在使用這些新指令時的幾個關鍵權衡與使用者的經驗:

The Value of History Curation

一些開發者認為完美地整理 Git 歷史是沒有必要的,建議在合併之前將所有提交進行 squash,這是一種更有效率的方法。其他人則將這些工具視為一種...

Sources