93

Subversion や CVS でブランチへの複数のマージを処理することは、経験しなければならないことの 1 つにすぎません。Mercurial (およびおそらく他の分散システム) でブランチとマージを追跡するのは非常に簡単ですが、その理由はわかりません。他の誰かが知っていますか?

私の質問は、Mercurial を使用すると、Subversions/CVS の中央リポジトリと同様の作業方法を採用でき、すべてがうまく機能するという事実に由来しています。同じブランチで複数のマージを行うことができ、コミット番号とタグ名が書かれた無限の紙切れは必要ありません。

Subversion の最新バージョンには、ブランチへのマージを追跡する機能があるため、同じ程度の手間がかからないことは知っていますが、これは彼らの側では大規模で主要な開発であり、開発チームが行うすべてのことを行っているわけではありません。するのが好きです。

すべてが機能する方法には、根本的な違いがあるはずです。

4

6 に答える 6

115

Subversion (および CVS) では、リポジトリが何よりも重要です。git と mercurial では、同じようにリポジトリの概念はありません。ここでは変化が中心的なテーマです。

+1

CVS/SVN の問題点は、これらのシステム が変更の親子関係を記憶していないことにあります。Git と Mercurial では、コミットは複数の子を持つことができるだけでなく、複数の親を持つこともできます!

gitkこれは、グラフィカル ツールの 1 つまたはを使用して簡単に確認できますhg view。次の例では、ブランチ #2 はコミット A で #1 からフォークされ、その後一度マージされています (M で、コミット B とマージされます)。

o---A---o---B---o---C         (branch #1)
     \       \
      o---o---M---X---?       (branch #2)

A と B には 2 つの子があり、M には 2 つのがあります。これらの関係はリポジトリに記録されます。ブランチ #2 のメンテナーがブランチ #1 からの最新の変更をマージしたいとします。次のようなコマンドを発行できます。

$ git merge branch-1

ツールは、ベースが Bであることを自動的に認識します。これは、#2 のヒントの祖先であるコミット M に記録されているためです。また、B と C の間で何が起こってもマージする必要があるためです。CVS はこの情報を記録しません。 、バージョン 1.5 より前の SVN もそうではありませんでした。これらのシステムでは、グラフは次のようになります。

o---A---o---B---o---C         (branch #1)
     \    
      o---o---M---X---?       (branch #2)

ここで、M は、A と B の間で発生したすべての巨大な「押しつぶされた」コミットであり、M の上に適用されます。行為が完了した後、Mの場所の痕跡は(潜在的に人間が読めるコメントを除いて)残らないことに注意してください。から始まったのではなく、いくつのコミットが一緒に崩壊したのか - 歴史をはるかに突き通せないものにしています。

さらに悪いことに、2 回目のマージを実行することは悪夢になります。最初のマージの時点でのマージ ベースが何であったかを把握する必要があり (そして、最初にマージがあったことを知る 必要があります!)、次に、それを提示する必要があります。 M の上で A..B を再生しようとしないように、情報をツールに送信します。これはすべて、緊密なコラボレーションで作業する場合には十分に困難ですが、分散環境ではまったく不可能です。

(関連する) 問題は、「X には B が含まれていますか?」という質問に答える方法がないことです。ここで、B は潜在的に重要なバグ修正です。では、その情報をコミット時に記録しない理由はありません。なぜなら、それはマージ時にわかっているからです!

P.-S. -- 私は SVN 1.5 以降のマージ記録機能の経験はありませんが、ワークフローは分散システムよりもはるかに工夫されているようです。もしそうなら、それはおそらく、上記のコメントで述べたように、変更自体よりもリポジトリの編成に焦点が置かれているためです。

于 2008-09-04T20:32:43.123 に答える
12

Subversion(少なくともバージョン1.4以下)はマージされたものを追跡しないためです。Subversionの場合、マージは基本的に他のコミットと同じですが、Gitなどの他のバージョン管理では、マージされたものが記憶されます。

于 2008-09-04T16:02:52.197 に答える
7

Hgは、すでに提供されている回答のいずれにも触れずに、変更をマージするときに多くの情報を使用するため、優れたマージ機能を提供しました(hginit.com)。

たとえば、関数を少し変更してから別の場所に移動すると、Subversionはそれらの手順を実際には覚えていないため、マージするときに、新しい関数が突然現れたと思うかもしれません。 。Mercurialはこれらのことを個別に記憶しますが、関数が変更され、関数が移動されました。つまり、その関数も少し変更した場合、Mercurialが変更を正常にマージする可能性がはるかに高くなります。

もちろん、最後にマージされたもの(ここで提供されるほとんどの回答で対処されたポイント)を思い出すことも大きな勝利です。

ただし、Subversion 1.5以降では追加のマージ情報がSubversionプロパティの形式で保存されるため、両方の改善には疑問があります。その情報が利用可能であるため、SubversionマージがHgやGitほど正常にマージを実装できなかった明確な理由はありません。そうかどうかはわかりませんが、Subversionの開発者がこの問題を回避しようとしているようです。

于 2010-07-05T13:27:13.093 に答える
4

これは部分的には、Subversion が改訂の絶対的なタイム ラインとともに中央サーバーのアイデアを持っているためだと思います。Mercurial は真に分散されており、絶対的なタイム ラインへのそのような参照はありません。これにより、Mercurial プロジェクトはサブプロジェクトごとに機能を追加してサイクルをテストするためのブランチのより複雑な階層を形成することができますが、チームは更新を押して完了させることができないため、最新の状態を維持するためにマージをより積極的に管理する必要があります。 .

于 2008-09-04T15:55:29.437 に答える
3

Subversion (および CVS) では、リポジトリが何よりも重要です。git と mercurial では、同じようにリポジトリの概念はありません。ここでは変化が中心的なテーマです。

どちらをどのように実装するかについてはあまり考えていませんが、私の印象 (苦い経験と多くの読書に基づく) は、この違いが非リポジトリ ベースのシステムでのマージと分岐を非常に簡単にするものであるということです。

于 2008-09-04T15:56:42.010 に答える
1

私は Subversion の経験しかありませんが、TortoiseSVN のマージ画面は恐ろしく複雑です。幸いなことに、ドライランボタンが含まれているため、正しく実行しているかどうかを確認できます. 複雑なのは、何をどこにマージするかの構成にあります。マージの設定が完了すると、通常、マージはうまくいきます。次に、すべての競合を解決してから、マージされた作業コピーをリポジトリにコミットする必要があります。

Mercurial がマージの設定を簡単にできるなら、Subversion よりも 100% 簡単にマージできると言えます。

于 2008-09-04T15:40:21.783 に答える