2012-03-20 37 views
19

我有一個腳本在構建服務器上以非交互模式運行一些Mercurial命令。其中一個命令會合並兩個分支,並且在合併期間.hgtags文件中始終存在衝突,這是因爲構建腳本的方式。如何在Mercurial中自動合併.hg標籤?

如何強制Mercurial始終使用來自兩個文件的更改合併.hgtags文件,先從一個文件然後從另一個文件進行更改?

例如,如果我合併文件是

A 
B 
C 

A 
B 
D 

我想的結果是

A 
B 
C 
D 

我猜我需要一個自定義合併工具。什麼工具提供此功能?

回答

31

請參閱answer below通過Magras德拉曼恰與水銀3.1更好的解決方案。以下是針對舊版Mercurial的更簡單更幼稚的解決方案。


是的,你需要配置自定義merge tool.hgtags文件。 Mercurial沒有爲.hgtags提供任何特殊的合併工具,您可以使用常規的三向合併工具手動合併它。

衝突在.hgtags文件可以有兩種類型:

  • 傻衝突:這是你的情況並沒有真的在這裏發生衝突。什麼情況是,一個分支具有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 
    

    ,另一支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    979c049974485125e1f9357f6bbe9c1b548a64c3 D 
    

    每個標籤代表一個確切的變更,所以這裏沒有衝突。當然,合併應該是工會上的兩個文件:

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 
    979c049974485125e1f9357f6bbe9c1b548a64c3 D 
    
  • 真實衝突:有一個分支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C 
    

    ,另一支有

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A 
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B 
    979c049974485125e1f9357f6bbe9c1b548a64c3 C 
    

    這裏有一個真正的衝突:hg tag C在兩個分支上完成,但t ags指的是不同的變更集。解決這個問題是一項手動任務。

如果你能保證你只有傻衝突和你只有每一個變更標籤,那麼你可以使用

hg log -r "tagged()" --template "{node} {tags}\n" > .hgtags 

生成一個新文件.hgtags。關鍵的洞察是Mercurial 知道如何在內部合併標籤!當你有兩個不同的.hgtags文件頭時,它總是這樣做。上述模板僅基於此內部合併生成新的.hgtags文件。

如果可能每變更一個以上的標籤,則上述不會工作 - 所有的標籤都印上一條線,所以你得到一個標籤foo bar,而不是兩個標籤foobar的。然後,您可以使用此style file代替:

changeset = "{tags}" 
tag = "{node} {tag}\n" 

它輸出每標籤一條線,而不是變更集。在某處保存此樣式並配置合併工具:

[merge-tools] 
hgtags.executable = hg 
hgtags.args = log -r "tagged()" --style ~/tmp/tags-style > $output 
hgtags.premerge = False 
hgtags.priority = -1000 

[merge-patterns] 
.hgtags = hgtags 

您現在已經自動標記合併。還有一些注意事項:

  1. 三個或更多的頭:如果您在合併時有兩國元首該方法僅適用。如果您有三個或更多頭,則可能會重新顯示已刪除的標籤。如果您有頭X,Y和Z,並且標記A在X中被刪除,則Mercurial通常能夠確定總體上刪除了A。它基於X的.hgtags文件中的000...0 A行執行此操作。但是,如果您將X和Y合併爲W,則建議的方法將不包含任何此類000...0 A行。來自Z的A的定義現在會突然生效並重新引入A

  2. 真實衝突:如果您有.hgtags真正的衝突,那麼上面的方法將默默地挑標籤從最近的頭部你。合併工具基本上將hg tags保存在.hgtags中,並且具有多個頭的hg tags的行爲是explained in the wiki。由於hg tags無條件地讀取並默默合併來自所有主管的.hgtags文件,因此使用這種簡單的方法我們無能爲力。處理這個問題需要一個更大的腳本來讀取兩個.hgtags文件並檢測衝突。

+0

有關解決愚蠢衝突的合併工具,請參閱https://bitbucket.org/xrstf/tagsmerger/wiki/Home。 :) – xrstf 2012-03-20 11:11:25

+0

@xrstf:其實我前幾天看到了這個。我不推薦它,因爲我認爲在有兩個以上的人頭時它不能正常工作。簡單地刪除'000 ... 0'行將重新引入標籤,就像我在我的答案中解釋的那樣。 – 2012-03-20 12:05:02

+0

非常好,我鼓掌!我可以問,這些notrs會出現在Aragost的網站上嗎?我們會在這裏丟失它 – 2012-03-21 00:38:50

-2

你應該試試diffmerge,太棒了!

+2

我覺得OP正在尋找一種**自動**合併這些文件的方法。 – krtek 2012-03-20 07:06:12

+0

對於*方式*,您可以隨意編輯衝突的文件,但如果涉及很多衝突,那將會很頭疼,這就是爲什麼我推薦一個像* diffmerge *這樣的好工具。沒有這樣的工具可以幫助你自動解決衝突,一個工具會幫助你這樣做。 – neevek 2012-03-20 07:12:55

1

無法通過執行無人蔘與合併來自動解決合併衝突。沒有合併(即選擇「只有我」或「只有其他」)它將起作用。

恐怕你的計劃工作流程糟糕 - 建立服務器一定不要執行任何操作,哪些修改源。這是人類和人類選擇的任務。

但我想,.hgtags中的確切數據必須爲構建服務器(它使用自己的克隆,而不是任何人填充,我希望?!),因此您可以在命令中定義任何合併策略,並具有壞,用數據丟失).hgtags以任何語言合併

順便說一句,「首先從一個,然後從其它」,僅使用形式邏輯,用於對

A 
B 
C 

A 
B 
D 

表示ABCABD導致

+1

在解決衝突的情況下,「首先從一個,然後從另一個」通常是指在結果文件中使用來自兩個文件的_conflicted_行:首先從一個文件,然後從另一個文件。這是任何圖形合併工具的標準功能,所以我認爲之前使用過的所有人都會理解我的意思。 – 2012-03-20 07:50:52

+1

這是正確的「在大多數情況下」,但正如@MartinGeisler所建議的,在這種特殊情況下存在解決方案。另外,您不應該在不瞭解更多的情況下批評OP工作流程。 – krtek 2012-03-20 08:50:39

+2

@krtek - 構建服務器不能修改代碼,只能構建。我保留向所有人陳述真相的權利 – 2012-03-20 09:31:47

1

實際上您並不需要合併.hgtags文件。它可以在不同分支上有所不同,Mercurial將正確列出所有分支中的所有標籤。

我們使用merge-patterns configuration option來告訴Mercurial在合併.hgtags時使用本地分支。以下內容添加到您的存儲庫的hgrc文件:

[merge-patterns] 
.hgtags = internal:local 

在做涉及.hgtags文件合併,.hgtags將顯示爲修改,但不能改變的。

+1

不是一個好主意,你可以從另一個頭上鬆開標籤。 – Jesse 2014-05-27 08:54:00

10

Mercurial 3.1(2014-08-01)介紹internal:tagmerge。它被標記爲實驗,所以要小心。 這裏是changeset序言(你可以找到關於算法的詳細信息,如果您按照鏈接):

添加一個新的內部:tagmerge合併工具,它實現了一個自動合併算法善變的標記文件

的tagmerge算法能夠解決目前會觸發.hgtags合併衝突的大多數合併衝突。它沒有(也不能)處理的唯一情況是其中兩個標籤指向每個合併父親上的不同修訂,其相應的標籤歷史具有相同的等級(即相同的長度)。在所有其他情況下,合併算法將選擇屬於具有最高排名標記歷史的父級的修訂。合併標籤歷史記錄是兩個標籤歷史記錄的組合(特別注意儘可能將常見標籤歷史記錄組合在一起)。

該算法還處理標籤已被手動從.hgtags文件和其他類似的角落案件中刪除的情況。

除了實際合併來自兩個父母的標籤,考慮到基礎,算法還嘗試最小化合並標籤文件和第一個父標籤文件之間的差異(即,它試圖使合併標籤順序儘可能與第一個父母的標籤文件訂單相似)。

tagmerge只標記文件的工作,所以使用它,你應該設置合併圖案。要做到這一點每命令依據使用--config選項:

hg merge -r REV --config merge-patterns..hgtags=internal:tagmerge

還是要做到這一點每庫基礎上添加到您的回購配置.hg/hgrc此:

[merge-patterns] 
.hgtags=internal:tagmerge 
+0

Mercurial的新版本在合併涉及'.hgtags'文件時默認使用這種算法? – binki 2015-10-13 19:38:33

+0

@binki,我沒有看mer​​curial路線圖或郵件列表。一年前剛剛解決了這個問題,並且找到了我找到的解決方案。 – magras 2015-10-15 14:14:48

相關問題