Mercurialではじめる分散構成管理

第2回 「マージ」は怖くない ~ 分散した成果の集約

この記事を読むのに必要な時間:およそ 4.5 分

実は日常的に「マージ」しているCVS/Subversion

CVSやSubversionの使用経験のある人がMercurialの概要を聞いた場合,往々にして以下のような感想を漏らす事が多いように思われます。

頻繁にマージをしなければならないようなツールは使いたくない。

こういった感想を持たれる人は,おそらくCVSやSubversionにおける「ブランチのマージ」の面倒くささに懲りているのでしょう。

しかし,ちょっと待ってください。ブランチを使用しなければ,CVSやSubversionは本当に「マージ」が不要なのでしょうか?

答えはNOです。

CVSやSubversionを習得する際には,書籍やオンラインドキュメント等で,何度も何度も以下のような「指導」を受けていると思います。

頻繁にupdateを実施して,リポジトリから最新の成果を取り込み,衝突(conflict)の解消が最小限で済むようにしましょう。

それではCVSやSubversionにおける,日常的な衝突解消の流れを詳細に見てみましょう。

  1. リポジトリからcheckout
  2. ワーキングディレクトリで作業を実施
  3. 他の人が作業成果をcommit
  4. updateで変更の取り込み
  5. 衝突を解消してcommit

これを図にすると,図3のようになります。

図3 未記録成果ベースのマージ

図3 未記録成果ベースのマージ

「updateで変更の取り込み」は,⁠マージ」という用語こそ使用していないものの, ⁠ワーキングディレクトリの内容」「他の人の成果」「マージ」していることに他なりません。

つまり,CVSやSubversionの日常的なワークフローでも,実は頻繁にマージを行っていたわけです。

以上の事から,⁠マージの頻度」⁠=量)をもって分散リポジトリ形式の不便さを主張することは,意味を持たないことがお分かりでしょう。

Mercurialの「マージ」「commit済み成果ベース」

それでは次に,⁠マージの方式」⁠=質)について見てみましょう。

CVSやSubversionにおける,⁠commmit済み成果」「ワーキングディレクトリの内容」をマージする方式を,ここでは便宜上未記録成果ベースのマージと呼びます。

一方で,Mercurialでの「マージ」の流れは以下のようになります。

  1. ローカルリポジトリからupdate
  2. ワーキングディレクトリで作業を実施
  3. 作業成果をcommit
  4. 他のリポジトリからpullによる成果取り込み
  5. 2つの成果をmerge
  6. 衝突を解消してcommit

これを図にすると,図4のようになります。

図4 commit 済み成果ベースのマージ

図4 commit 済み成果ベースのマージ

「commit 済み成果」同士をマージしているこの方式を,ここでは便宜上commit 済み成果ベースのマージと呼びます(CVSやSubversionのブランチ間マージも,この形式です⁠⁠。

人によっては,以下のように考える方もいるかもしれません。

マージに先立ってcommitしなければならないのは面倒。

しかし,⁠未記録成果ベースのマージ」において,マージ対象となる「ワーキングディレクトリ」中の作業成果は,その時点ではどこにも記録されていません。それは即ち,マージ直前までのワーキングディレクトリ中の作業成果が,マージ作業の最中に霧散消失してしまう危険性と,常に隣り合わせであることを意味しています。

一方の「commit済み成果ベースのマージ」の場合,既にリポジトリに内容が記録されている「commit済み成果」をマージ対象としますから,そういったことは起こりません。

安全性の確保は,作業実施の際の心理的抵抗の低下を促すことでしょう。つまり,⁠マージの方式」⁠=質)では,むしろMercurialの方に利があるのです。

どうしても,次のように思えてしまう方もいるかもしれません。

CVSやSubversionでのブランチのマージは面倒だったので,きっとMercurialのマージも面倒に違いない。

しかし,次ページのMercurialでの実際のマージ手順を見れば,その簡単さに拍子抜けするのではないでしょうか。

追記:

正確には,ワーキングディレクトリの親チェンジセットに対して,update 先のチェンジセットが以下の条件を満たす場合に限り,"hg update" 実行時に「未記録成果ベースのマージ」が実施されます。

  • 直系の子孫であること
  • 同一の名前付きブランチ上にあること(= "hg log" での "branch" 表示が同一⁠

少人数での開発時には比較的この制約は成立し易いですが,前述したように,安全性の面からは「commit済み成果ベース」のマージをおすすめします。

著者プロフィール

藤原克則(ふじわらかつのり)

Mercurial三昧の日々が嵩じて, いつの間にやら『入門Mercurial Linux/Windows対応』を上梓。凝り性なのが災いして,年がら年中アップアップな一介の実装屋。最近は仕事の縁が元で,OpenSolarisに入れ込む毎日。