Mercurial 壓縮提交

2009 年 7 月 9 日

我最近用 Mercurial 壓縮了一些提交,因此認為值得發布一篇文章,以防其他人也有意這麼做。我不知道這是不是最佳程序,但對我來說似乎相當有效。

hg clone base working
# tip of base is revision 73
cd working
# do work, committing on the way
cd ..
hg clone working squash
cd squash
hg qimport -r 74:tip
hg qgoto 74.diff
hg qfold $(hg qunapp)
hg qfinish -a
cd ../base
hg pull ../squash

我執行的基本任務是相當嚴重的檔案和資料夾移動。我想要分幾個步驟執行此操作,以便在進行時檢查我的工作,但我想要在版本記錄中有一個單一提交。(我認為 git 使用 rebase 可以更輕鬆地執行此操作。)建立單一提交可以更輕鬆地了解發生了什麼事,特別是因為移動檔案往往會讓檢視儲存庫記錄變得複雜。移動檔案也會讓程序變得複雜,有幾次我最後使用無法運作的程序,因為它失去了追蹤移動的能力,我希望能夠執行 hg log -f,並查看移動前原始提交的時間和內容。

一開始我需要啟用 mq 分機(Mercurial 佇列),並將我的差異設定為 git 風格。Git 風格差異有助於正確追蹤檔案移動。

# in ~/.hgrc
[extensions]
mq=

[diff]
git=true 

以這種方式使用 Mercurial 時,似乎一般的工作方式是擁有多個儲存庫。Mercurial 鼓勵使用不同的儲存庫,而其他系統(例如 git 或 svn)會使用不同的分支。人們對此爭論不休,但這是 Mercurial 的工作方式。在此範例中,我將「base」設為我的原始儲存庫。

我的第一步是將 base 克隆到工作儲存庫中。

hg clone base working

此時,base(和工作)的提示是版本 73。我進行了檔案移動,並在進行過程中建立了幾個檢查點版本。

cd working
hg mv foo1 newdir/foo1
.. more hg mv ..
hg ci -m "moving around"
.. more hg mv ..
hg ci -m "moving around"
.. more hg mv and hg ci..
cd ..

在我完成時,最後一個版本是 80。

為了將它們壓縮成單一提交,我克隆了另一個儲存庫。

hg clone working squash

此時克隆很重要,因為我即將編輯記錄,因此希望保留原始記錄,直到我知道它已經運作為止。現在我移到其中。

cd squash

現在,我將我為版本所做的所有提交轉換為 Mercurial 修補佇列機制的修補程式。

hg qimport -r 74:tip

我將第一個變更設為目前的修補程式

hg qgoto 74.diff

我將所有修補程式壓縮成單一修補程式

hg qfold $(hg qunapp)

此摺疊修補程式的提交訊息將是所有個別提交訊息連結在一起。我想要一個單一訊息,作為我的乾淨提交。

hg qrefresh -m "reorganized files"

然後我將補丁轉換成常規提交。

hg qfinish -a

現在我有一個包含所有工作的單一提交。我查看它以確保一切正常,特別是對某些移動的文件執行測試 hg log -f 以確保歷史記錄仍然存在。一旦我確信一切正常,我就將單一變更集拉入基本儲存庫。

 
cd ../base
hg pull ../squash
  

看到多年來對版本控制系統的關注如何發生變化,這很有趣。早期,主要且唯一的目的是審核 - 能夠安全地返回到舊版本 - 主要用於診斷問題。然後注意力轉移到它們如何促進人們之間的協作。這並未取代審核的需要,而是建立在審核的基礎上。現在,人們更關注使用它們來提供代碼庫如何變化的敘述 - 因此需要像這樣的歷史重寫命令。同樣,這種需求建立在其他兩個需求之上,但引入了新的功能和新的緊張關係。

感謝我的同事 Chris Turner 的幫助,我也發現 此頁面 非常有用。