1. ホーム
  2. git

[解決済み] マージ Hg/Git vs. SVN

2022-06-01 18:01:26

質問

Hg (そして Git や...) は SVN よりもマージが得意だとよく読みますが、SVN が失敗するところ (あるいは SVN が手動介入を必要とするところ) で Hg/Git が何かをマージできるような実用的な例をこれまで見たことがありません。ブランチ/変更/コミット/...などの操作で、SVNが失敗する一方でHg/Gitは喜んで先に進めるようなステップバイステップのリストをいくつか掲載していただけませんか?実用的で、非常に例外的なケースではないものをお願いします...。

いくつかの背景:私たちは、各プロジェクト(または類似のプロジェクトのグループ)がそれ自身のリポジトリで、SVN を使用してプロジェクトに取り組んでいる数十人の開発者を持っています。私たちは、リリースおよび機能分岐を適用する方法を知っているので、あまり問題に遭遇することはありません (つまり、私たちは経験済みですが、克服することを学びました)。 Joel の問題 一人のプログラマーがチーム全体にトラウマを植え付けたり、ブランチを再統合するために 6 人の開発者が 2 週間必要であったりといった問題です。) 私たちには、非常に安定していてバグフィックスの適用にのみ使われるリリースブランチがあります。トランクは、1週間以内にリリースを作成できるほど安定している必要があります。そして、一人の開発者や開発者のグループが作業できるフィーチャーブランチがあります。そう、それらは再統合後に削除されるので、リポジトリを乱雑にすることはありません;)。

というわけで、私はまだSVNに対するHg/Gitの利点を見出そうとしています。実地経験を積みたいのですが、Hg/Git に移行できるような大きなプロジェクトはまだないので、いくつかの作り込まれたファイルだけを含む小さな人工プロジェクトで遊ぶことに留まっています。そして、これまでのところ、私はしばしばそれについて読んでいますが、自分自身で見つけることができなかったので、Hg/Gitの印象的な力を感じることができるいくつかのケースを探しています。

どのように解決するのか?

私自身はSubversionを使用していないのですが、Subversionを使用する前に リリースノート Subversion 1.5: マージ追跡 (基礎編) を見ると、フルバージョンでのマージ追跡の仕組みと以下のような違いがあるようです。 DAG のようなバージョン管理システムでのマージ追跡の仕組みとは次のような違いがあります。

  • trunk から branch へのマージは、branch から trunk へのマージとは異なります: trunk から branch へのマージには、何らかの理由で --reintegrate オプションに svn merge .

    Git や Mercurial のような分散型バージョン管理システムでは 技術的な トランクとブランチの間に技術的な違いはありません。すべてのブランチは同じように作成されます。 社会的 の違いはあるかもしれませんが)。 どちらの方向でもマージは同じように行われます。

  • を新たに用意する必要があります。 -g ( --use-merge-history ) オプションを svn logsvn blame で、マージ・トラッキングを考慮します。

    Git と Mercurial では、履歴 (ログ) と注釈を表示する際に、マージ追跡が自動的に考慮されます。 Git では、最初の親だけを追いかけるよう要求するには --first-parent (同様のオプションは Mercurial にもあると思います) を使って、マージ追跡の情報を git log .

  • 私が理解したところでは svn:mergeinfo プロパティはコンフリクトに関するパスごとの情報を保存します (Subversion はチェンジセットベースです)。一方 Git と Mercurial では、複数の親を持つことができる単純なコミットオブジェクトです。

  • 既知の問題 Subversion のマージ追跡のためのサブセクションは、繰り返し/周期的/反射的マージが正しく機能しない可能性があることを示唆しています。 それは、次のような履歴を持つ 2 番目のマージが正しいことを行わないかもしれないことを意味します (「A」はトランクまたはブランチ、「B」はブランチまたはトランクのそれぞれである可能性があります)。

    *---*---x---*---y---*---*---M2 <-- A
             \ \ /
              --*----M1---*---*---*---/ <-- B
    
    

    この場合、上記のASCII-artは壊れてしまいます。リビジョン 'x' でブランチ 'A' からブランチ 'B' が作成 (fork) され、その後リビジョン 'y' でブランチ 'A' がマージ 'M1' としてブランチ 'B' に、そして最後にブランチ 'B' がマージ 'M2' としてブランチ 'A' にマージされた場合です。

    *---*---x---*-----M1--*---*---M2 <-- A
             \ / / 
              \-*---Ъ-*---y---*---*---/ <-- B
    
    
    

    この場合、上のアスキーアートは壊れてしまいます。リビジョン 'x' で 'A' から 'B' が作成 (フォーク) され、'y' で 'M1' として 'A' にマージされ、その後 'M2' として再び 'A' にマージされます。

  • の高度なケースを Subversion はサポートしないかもしれません。 十字形マージ .

    *---b-----B1--M1--*---M3
         \ \ / /
          \ X /
           \ / \ /
            \--♪♪♪♪「B2--M2--*」。
    
    

    Git は "recursive" マージ戦略を使って、実際にはこの状況をうまく処理します。 Mercurialはどうでしょうか。

  • "既知の問題"。 例えば、一方がファイル名を変更し (おそらく変更も)、他方がファイル名を変更せずに (古い名前で) ファイルを変更する場合、マージ追跡が機能しない可能性があることを警告しています。

    Git と Mercurial はどちらも、実際にはこのようなケースをうまく処理します。Git では リネーム検出 を、Mercurial は リネームトラッキング .

HTH