「入門TortoiseHg+Mercurial」発売中(詳細は「執筆情報」参照)


リモートリポジトリ

CVS に代表されるリポジトリ集中型 SCM では、 単一の「リポジトリ」を作業者間で共有する形態を取りますが、 Mercurial のような分散リポジトリ型 SCM の場合、 全ての作業者の手元に「リポジトリ」が存在します。

但し、全ての作業者の手元に 同一内容の「リポジトリ」が存在するのではなく、 各自の作業によって生じた「リポジトリ」間の更新内容をお互いに伝播しあうことで、 最終的に全体としての一貫性を保つようになっています。

備考: 「集中リポジトリ型」と「分散リポジトリ型」の違いは、 ftp によるダウンロードと P2P によるファイル共有の違い、 と考えるとイメージしやすいかもしれません。

そのため、 手元の単一のリポジトリ(= ローカルリポジトリ)に対する操作に加えて、 複数の外部リポジトリ(= リモートリポジトリ)との連携が必要となります。

更新伝播の概要

以下、 作業者 A と作業者 B の作業用リポジトリと、 成果共有用の Master リポジトリの連携により、 お互いの作業成果を共有する手順を説明します。

始めに、A および B が Master のリポジトリ内容を "hg clone" ないし "hg pull" により複製します (これは CVS 利用における checkout ないし update に相当します)。

以後、図中でリポジトリ間を結ぶ矢印は、 更新データが伝播する方向を表します。

A および B がそれぞれのリポジトリに更新内容をコミットします。 この時のコミット内容は、 あくまでそれぞれの作業者の作業用リポジトリにしか存在していません。

"

hg push" により A が自身の更新を Master に伝播することで、 Master にも A での更新内容が存在するようになります。

これ以降は他の開発者も Master から A の更新成果を取得することが出来ます。 言い換えるなら、 Master に更新成果を伝播しなければ、 自身の更新成果は他の開発者からは一切見えません

備考: ローカルリポジトリは言ってみれば、 「プライベートなブランチ」のようなものです。

Mercurial では「リポジトリを複製する(= ローカルリポジトリの作成) ことそのものが、 ブランチを作るようなもの」と言っています。

この時点で B が自身の更新を "hg push" により Master に伝播しようとすると、 Master 側のヘッド数が増える(1 ⇒ 2)ことになるため、 伝播要求は基本的には拒否されます。

これは、 CVS で言うところの main trunk における衝突に相当します。

備考: ブランチの新規作成を行う場合など、 Master 側のヘッド数が増えることがわかっている際には、 "hg push -f" で強制的に Master 側に更新内容を伝播することが出来ます。

そこで、 B は現時点での Master の内容を "hg pull" により取り込み、 更に自身の更新内容とマージします (= A の更新と B の更新のマージ)。

この時点の B の更新内容を "hg push" により Master に伝播した場合、 Master 側のヘッド数は増えません(1 ⇒ 1)から、 B から Master への更新伝播は受理されます。

この時点で A が (B の更新結果の取り込み/マージを行う事無く) 追加的な更新を "hg push" により Master に伝播しようとすると、 やはり Master 側のヘッド数が増える(1 ⇒ 2)ことになるため、 伝播要求は拒否されます。

以後は、 相互に更新内容の取り込み/マージを繰り返すことで、 A と B の間で更新の伝播/整合性の維持を図ることが出来ます。

このように、 更新伝播の際に常にマージの必要性が付き纏うことを、 「面倒なコスト」と捕らえるか「利便性の対価」と捕らえるかは、 利用者の状況次第と言えるでしょう。 「オフライン時における履歴参照/差分取得/コミット」や、 「システム構成例」 に示すような構成管理形態に価値を見出せるのであれば、 マージの実施は十分安い対価だと思います。

更新伝播手段

Mercurial は以下の更新伝播手段を提供しています。

「即時性」は、「ローカル⇒リモート」における伝播実施の際に、 伝播内容の反映が即時実施されるか否か」を表しています (「リモート⇒ローカル」の伝播実施は常に即時性を持っています)。 「即時性」が無い伝播手段は、 伝播内容を何らかの中間形式に出力しますので、 それらに関しては中間形式について補足してあります。

「選択的取得」は、 特定のチェンジセットに限定して伝播することが可能であるか否かを表しています。

ローカル
⇒リモート
リモート
⇒ローカル
即時性
(中間形式)
選択的
取得
備考
-- clone 不可 他のリポジトリ内容のコピー。
push pull リモートの head を増やす push は、 -f オプション付きで実行する必要がある。 pull における head の増加は許容される。
outgoing incoming -- 不可 更新の有無の検出のみで、 更新は行わない
export import
(unified diff)
バイナリファイルの更新内容をはじめとして、 伝播されない情報がある
bundle unbundle
(独自バイナリ)
不可

「完全性」という点からは export/import は bundle/unbundle に劣りますが、 例えばパッチの取り込みは内容レビュー後に行いたい (= 変更内容の可読性が欲しい)、 というような場合は十分有用です。


次節「システム構成例」へ