22

ビルド サーバー上で非対話モードでいくつかの Mercurial コマンドを実行するスクリプトがあります。.hgtagsコマンドの 1 つは 2 つのブランチをマージしますが、ビルド スクリプトの設定方法が原因で、マージ中にファイル内で常に競合が発生します。

.hgtagsMercurial に、最初に一方から、次に他方から、両方のファイルの変更を常に使用してファイルをマージさせるにはどうすればよいですか?

たとえば、マージするファイルが

A
B
C

A
B
D

私は結果が欲しい

A
B
C
D

カスタム マージ ツールが必要になると思います。この機能を提供するツールは何ですか?

4

5 に答える 5

31

Mercurial 3.1のより良い解決策については、Magras deLaManchaによる以下の回答を参照してください。以下は、古いバージョンのMercurial用のよりシンプルでナイーブなソリューションです。


はい、ファイルのカスタムマージツールを構成する必要があり.hgtagsます。Mercurialには特別なマージツールはありません.hgtags。通常の3方向マージツールを使用して手動でマージする必要があります。

.hgtagsファイル内の競合には、次の2つのタイプがあります。

  • 愚かな対立:これはあなたが抱えている状況であり、ここでは実際には対立はありません。何が起こるかというと、1つのブランチが

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
    

    そして他のブランチは

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    979c049974485125e1f9357f6bbe9c1b548a64c3 D
    

    各タグは正確に1つのチェンジセットを参照するため、ここで競合は発生しません。もちろん、マージは2つのファイルの結合である必要があります。

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
    979c049974485125e1f9357f6bbe9c1b548a64c3 D
    
  • 本当の対立: 1つのブランチがあります

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    12e0fdbc57a0be78f0e817fd1d170a3615cd35da C
    

    そして他のブランチは

    f40273b0ad7b3a6d3012fd37736d0611f41ecf54 A
    0a28dfe59f8fab54a5118c5be4f40da34a53cdb7 B
    979c049974485125e1f9357f6bbe9c1b548a64c3 C
    

    ここには実際の競合があります。hg tag C両方のブランチで実行されましたが、タグは異なるチェンジセットを参照しています。これを解決するのは手動の作業です。

ばかげた競合のみが発生し、チェンジセットごとにタグが1つしかないことを保証できる場合は、次を使用できます。

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

新しい.hgtagsファイルを生成します。重要な洞察は、Mercurialがタグを内部でマージする方法を知っているということです!これは、.hgtagsファイルが異なる2つのヘッドがある場合に常に実行されます。上記のテンプレートは、.hgtagsこの内部マージに基づいて新しいファイルを生成するだけです。

チェンジセットごとに複数のタグがある場合、上記は機能しません。すべてのタグが1行に印刷されるため、2つのタグとfoo barの代わりにタグを取得します。その後、代わりにこのスタイルファイルを使用できます。foobar

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

チェンジセットではなく、タグごとに1行を出力します。このスタイルをどこかに保存し、マージツールを構成します。

[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. 3つ以上のヘッド:このテクニックは、マージ時に2つのヘッドがある場合にのみ機能します。ヘッドが3つ以上ある場合は、削除したタグが再表示される可能性があります。ヘッドX、Y、およびZがあり、タグAがXで削除されている場合、Mercurialは通常、A全体的に削除されていることを認識できます。これは、X000...0 Aのファイル内の行に基づいて行われ.hgtagsます。ただし、XとYをマージしてWを取得する場合、提案されたアプローチにはそのような行は含まれません000...0 A。from Zの定義がA突然有効になり、再導入されAます。

  2. 実際の競合:に実際の競合が.hgtagsある場合、上記の方法では、最新のヘッドからタグがサイレントに選択されます。マージツールは基本的にに保存hg tagsされ、複数のヘッドを使用し.hgtagsた場合の動作はwikiで説明されています。すべてのヘッドからファイルを無条件に読み取り、サイレントにマージするため、この単純なアプローチでは何もできません。これに対処するには、2つのファイルを読み取り、競合を検出するより大きなスクリプトが必要になります。hg tagshg tags.hgtags.hgtags

于 2012-03-20T08:27:18.567 に答える
13

Mercurial 3.1 (2014-08-01)でinternal:tagmergeが導入されました。実験的とマークされているので、注意してください。これはチェンジセットのプリアンブルです(リンクをたどると、アルゴリズムの詳細を見つけることができます):

Mercurial のタグ ファイルの自動マージ アルゴリズムを実装する新しい internal:tagmerge マージ ツールを追加します。

tagmerge アルゴリズムは、現在 .hgtags マージ競合を引き起こすほとんどのマージ競合を解決できます。処理しない (そして処理できない) 唯一のケースは、2 つのタグが各マージ親の異なるリビジョンを指し対応するタグ履歴が同じランク (つまり、同じ長さ) を持つ場合です。それ以外の場合、マージ アルゴリズムは、タグ履歴のランクが最も高い親に属するリビジョンを選択します。マージされたタグ履歴は、両方のタグ履歴を組み合わせたものです (可能な場合、共通のタグ履歴を組み合わせるように特別な注意が払われます)。

このアルゴリズムは、タグが .hgtags ファイルから手動で削除されたケースや、その他の同様のコーナー ケースも処理します。

ベースを考慮して、2 つの親からのタグを実際にマージすることに加えて、アルゴリズムは、マージされたタグ ファイルと最初の親のタグ ファイルとの差を最小限に抑えようとします (つまり、マージされたタグの順序を次のようにしようとします)。最初の親のタグ ファイルの順序で可能)。

tagmergeはタグファイルでのみ機能するため、これを使用するにはmerge-patternsを設定する必要があります。コマンドごとにこれを行うには、--configオプションを使用します。

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

または、リポジトリごとにこれを行うには、これをリポジトリ構成に追加します.hg/hgrc

[merge-patterns]
.hgtags=internal:tagmerge
于 2014-09-24T09:09:40.447 に答える
2

実際に .hgtags ファイルをマージする必要はありません。ブランチごとに異なる可能性があり、Mercurial はすべてのブランチのすべてのタグを正しくリストします。

merge-patterns構成オプションを使用して、.hgtags のマージを行うときにローカル ブランチを使用するように Mercurial に指示します。以下をリポジトリの hgrc ファイルに追加します。

 [merge-patterns]
 .hgtags = internal:local

.hgtags ファイルを含むマージを実行すると、.hgtags は変更済みとして表示されますが、変更されません。

于 2012-03-20T16:55:40.903 に答える
1

無人マージを実行してマージ競合を自動的に解決することはできません。マージしない場合(つまり、「自分だけ」または「その他のみ」を選択する場合)は機能します。

恐れ入りますが、ワークフローの計画が不適切です。build-serverは、ソースを変更するアクションを実行してはなりません。それは人間と人間の選択のための仕事です。

しかし、.hgtags内の正確なデータは、build-serverの値である必要があると思います(独自のクローンを使用し、誰にも入力されないことを願っていますか?!)。したがって、コマンドで任意のマージポリシーを定義し、(bad、with data -損失).hgtagsがマージされました

ところで、ペアの場合、正式な論理のみを使用して、任意の言語で「最初に一方から、次にもう一方から」

A
B
C

A
B
D

ABCABD結果を意味します

于 2012-03-20T07:39:03.093 に答える
-1

あなたはdiffmergeを試してみるべきです、それは素晴らしいです!

于 2012-03-20T07:04:50.830 に答える