Subversion(およびCVS)では、リポジトリが何よりも重要です。gitとmercurialでは、実際には同じようにリポジトリの概念はありません。ここでは、変更が中心的なテーマです。
+1
CVS / SVNの面倒は、これらのシステム
が変更の親子関係を覚えていないという事実から来ています。GitとMercurialでは、コミットは複数の子を持つことができるだけでなく、複数の親を持つこともできます!
それは簡単にグラフィカルなツールのいずれかを使用して観察し、することができますgitk
かhg
view
。次の例では、ブランチ#2はコミットAで#1から分岐され、それ以降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+マージレコーディング機能の経験はありませんが、ワークフローは分散システムよりもはるかに不自然なようです。それが実際に当てはまる場合は、おそらく上記のコメントで述べたように、変更自体ではなくリポジトリの編成に重点が置かれているためです。