構成管理とは、複数の版を持つ情報群を管理する手順のことです。最も単純な手法では、多くの人々がこれを手動で行います。ファイル更新時には、直前の版に利用した値よりも大きな値を割り当ててから、その値を含めた新しい名前でファイルを保存する、といった具合 です。
しかしながら、たった1つのファイルであっても、複数の版を手動で管理する作業は間違いがちですので、この手順を自動化するソ フトウェアツールには長い歴史があります。初期の構成管理を自動化するツールは、単一ユーザによる単一ファイルの版管理の補助を意図していました。ここ数十年の間に、構成管理ツールの適用範囲は大変拡大されてきました。現在では、複数 のファイルに対する複数のユーザの共同作業を管理するまでになっています。今時の最善の構成管理ツールは、共同作業する数千人のユーザによって、数十万のフィルからなるプロジェクトのデータが複製されても、びくともしませ ん。
プロジェクトにおいて、読者であるあなたや、あなたのチームが自動化された構成管理ツールを使用したくなるのは、以下のような理由があるからではないでしょうか。
これらの理由の殆どが — 少なくとも理屈の上では — 一人きりのプロジェクトでも、百人と共同作業するプロジェクトでも有効です。
これら2つの規模の異なるケース(“lone hacker” と “huge team”)のそれぞれにおいて、構成管理ツールの実用性に関する重要な問題は、ツールから得られる利益とそのコストをどのように比較するか、という点にあります。理解や使用が難しい構成管理ツールは、 コストが高く付くでしょう。
構成管理のツールとプロセス抜きでは、 500 人からなるプロジェクトはおそらく自分自身の重みで、すぐにでも崩れてしまうでしょう。この場合、構成管理ツール抜きには失敗が保証されたようなものですから、それを思えば、構成管理ツールを利用するコストについ ては考えるまでも無いでしょう。
一方で、一人での “quick hack” の場合、構成管理ツールを使うコストはプロジェクト全体のコストと同一の筈ですから、構成管理を使う余地は殆ど無いように見えるかもしれません。しかし、それは本当でしょか?
Mercurial はこれら両方の規模の開発を上手にサポートします。わずか数分で基本を習得でき、その低オーバヘッドのお陰で最も小さなプロジェクトにも簡単に構成管理を適用できます。
構成管理ツールの単純さは、難解な概念や、本当にやろうとしていることと心理的に競合するコマンド列といったものを、大量に身に付ける必要が無いことを意味します。同時に、 Mercurial の高性能さと P2P 的特性は、大きなプロジェクトへの利用へと苦も無く拡大できます。
運営の下手なプロジェクトを救える構成管理ツールはありませんが、良いツールを選択することで、プロジェクトでの作業における 滑らかさが全く違ってきます。
構成管理は多様な領域なので、実際には統一された名前や頭字語語がありません。
よく目にする一般的な名称および略称を以下に列挙します。
これらの用語は実際にはそれぞれ異なる意味を持っている、と主張する人もいますが、実際にはお互いに非常に重 複した意味を持っているので、これらに対して個別にあれこれ言うことには賛同もできませんし、有用性もありませ ん2 。
最も有名な昔の構成管理ツールは、 Bell Labs の Marc Rochkind が 1970 年代初頭に実装した SCCS (Source Code Control System)です。 SCCS は個別のファイルに対して機能し、プロジェクトに従事する全ての作業者は、単一システム上の共有作業領域へ のアクセス権が必要でした。ある時点でのあるファイルの変更は、ただ一人の作業者のみが可能で、ファイルのアクセスはロックにより 調停されていました。ファイルをロックしたまま開放し忘れてしまい、管理者の補助無しには他の人がファイルを変更できなくしてしま うことは、良くあることでした。
SCCS のフリーな代替ツールとして 1980 年代初頭に Walter Tichy が RCS (Revison Control System)と呼ぶプログラムを開発 しました。 SCCS と同様、 RCS の利用には、単一の共有作業領域での作業と、複数の作業者が同時に改変するのを防ぐためのロック が必要でした。
1980 年代後期、 Dick Grune は RCS を用いて、当初 cmt と呼ばれるシェルスクリプト群を実装し、後にこれらは CVS (Concurrent Versions System)と改名されました。 CVS における大きな変革は、各開発者ごとの作業領域において、開発者が平行 且つ幾分独立した作業ができるようになったことです。 SCCS や RCS では良くあった、いつでも他人の足を踏んでしまう状況が、開 発者ごとの作業領域の導入によって防がれるようになりました。各開発者は、プロジェクトに関する全てのファイルの複製を持ち、各自 の複製を独立して変更することができました。中央のリポジトリへの変更のコミットに先立って、変更内容のマージをする必要がありま した。
Brian Berliner は Grune のオリジナルスクリプトを元に C で書き直し、以来現代版の CVS へと発展するコードを 1989 にリリー スしました。 CVS はその後、「クライアント・サーバ」アーキテクチャの導入により、ネットワーク接続越しの操作を可能とする機能 を獲得しました。 CVS のアーキテクチャは中央集約的なもので、サーバのみがプロジェクトの履歴のこぴーを持っています。クライア ント側の作業領域は、プロジェクトファイルの最新版を複製したものと、サーバの場所等を知るためのわずかなメタデータを 持っているだけです。 CVS は非常に成功していて、おそらく世界で最も広く使用されている構成管理システムでしょ う。
Sun Microsystems は 1990 年代初頭に、 TeamWare と呼ばれる分散構成管理システムのはしりとなるものを開発しました。 TeamWare における(個人の)作業領域は、プロジェクトの完全な複製を格納しています。 TeamWare には「中央リポジトリ」という概念がありません( CVS は履歴格納を RCS に依存していましたが、 TeamWare は SCCS を利用していました)。
1990 年代が進むにつれて、問題意識から CVS に関する問題が多く顕在化してきました。例えば CVS は、複数のファイルに対する 同時更新を、論理的に不可分な単一の作用としてまとめる替わりに、ファイルごとに個別に記録しています。また、ファイル階層を上手 く管理できないため、ファイルやディレクトリを改名することで、容易にリポジトリを混乱させることができます。なお悪いことに、 CVS 自身のソースコードは読むにも保守するにも難解なため、アーキテクチャ上の問題点を修正する “苦痛度” は法外なものでし た。
CVS の開発を行っていた Jim Blandy および Karl Fogel の二人は、より良いアーキテクチャを持ち、尚且つコードが綺麗なツール で CVS を置き換えるプロジェクトを、 2001 年に始めました。結果として生み出された Subversion は、 CVS の中央集約型クライア ント/サーバモデルからは離れなかったものの、複数ファイルの不可分コミットや、より良い名前空間の管理、および CVS よりも概ね 良好なツールと言うに足るその他の多くの機能を持っています。初回のリリース以来、その人気は速やかに上昇していま す。
それと概ね同時期に、 Graydon Hoare は Monotone と呼ばれる野心的な分散構成管理システムに取り掛かり始めました。 Monotone は、 CVS 設計上の多くの問題に取り組み、 P2P アーキテクチャを持つ一方で、多くの革新的な点において初期の(そして その後の)構成管理ツールから飛び抜けています。 Monotone は、暗号で用いられるハッシュ値を識別子として使用しており、異なる 由来のコードにとって不可欠な “信頼” の概念を持っています。
Mercurial は 2005 年に誕生しました。設計上の幾つかの見地において Monotone から影響を受ける一方で、 Mercurial は利用の簡 便性、性能の高さ、および大規模プロジェクトへの適用性に主眼を置いています。
過去40年に渡る構成管理ツールの開発と利用における紛れも無い傾向として、構成管理ツールの利用者は、利用しているツールの機能 に精通すると共に、ツールの制約によって抑制されるようです。 XXXXXX There has been an unmistakable trend in the development and use of revision control tools over the past four decades, as people have become familiar with the capabilities of their tools and constrained by their limitations.
最初の世代は、単一ファイルを各自のコンピュータで管理することから始まりました。この世代のツールは、手動による場当たりな 構成管理に比べれば大きな前進ではありましたが、排他による操作モデルと、単一コンピュータ上での利用を前提とした設計のため、小 さく緊密なチームでの利用に限定されていました。
第二世代は、ネットワーク主体のアーキテクチャへの移行と、プロジェクト全体の一括管理によって、これらの制約を緩和しまし た。しかし、プロジェクト規模が大きくなればなるほど、新たな問題が発生しました。クライアントはサーバと頻繁 に連携する必要があるため、サーバは大規模プロジェクトへの適用が問題になりました。信頼性の低いネットワーク 接続では、遠隔ユーザがサーバと全く連携ができないこともありました。オープンソースプロジェクトが匿名の読み 込み専用アクセスを開放するにつれ、リポジトリへのコミット権限を持たない人々は、構成管理ツールの通常の方法 では自分たちの変更が記録できず、それ故にプロジェクトに対して働きかけることができないことに気付き始めまし た。
現世代の構成管理ツールは、事実上 P2P です。これらは、単一の中央サーバに対する依存を持たず、そのため構成 管理データを必要な場所に分散することが可能です。インターネットを介した連携における課題は、技術的な制約に 関するものから、選択 (of what ?) と合意 (of what) 形成の問題へと移行しつつあります XXXX。 Collaboration over the Internet has moved from constrained by technology to a matter of choice and consensus. 最新のツール は、オフライン状況でも無制限に独立して操作でき、ネットワーク接続は他のリポジトリとの同期にのみ必要とされま す。
前世代への対抗馬として、ここ数年の間に分散構成管理ツールが堅牢且つ便利になってきてはいるものの、古いツールを利用している 人々は、必ずしも分散構成管理ツールの長所に気付いているわけではありません。中央集約的型(ツール)と比較して、分散型(ツー ル)の優れている点が幾つかあります。
開発者個人にとっては、中央集約型と比較した場合、概ねいつでも分散型の方が高速です。これは、中央集約型では殆どのメタデー タが中央サーバ上にしか存在しないため、多くの定型処理の度にネットワーク越しにサーバとの通信が必要、という単純な理由のためで す。分散型の場合は、全てのメタデータを手元に格納しています。他の全てが同じだとしても、ネットワーク越しの通信は中央集約型に とってのオーバヘッドとなります。構成管理ツールとの対話に多くの時間を費やそうと言うのですから、テキパキと動く応答性の良い ツールの価値を軽視してはいけません。
繰り返しになりますが、分散型はメタデータを何箇所にも複製できるので、サーバ環境の気まぐ れ3 は気に なりません。中央集約型でサーバが火を噴いた場合には、バックアップメディアの信頼性と、最後のバックアップが最近のものであるこ とを祈るに違いありません。分散型の場合、各開発者のコンピュータ上に無数のバックアップが存在することになりま す。
分散型は中央集約型の場合よりも、ネットワークの信頼性による影響を受けません。それどころか、非常に限定的な幾つかのコマン ドを除けば、中央集約型ではネットワーク接続抜きには何もできません。分散型の場合、作業中にネットワーク接続が切れても、その事 に気付かないかもしれません。他のコンピュータ上のリポジトリとの連携だけはできなくなりますが、手元のリポジトリとの連携と比べ れば、そのような連携が必要な事態はわずかなものです。分散しているな共同作業チームの場合には、これは重要で す。
ソースをハッキングしてみようと思ったオープンソースのプロジェクトが、分散構成管理ツールを使用していた場合、自身をプロジェク トの “中核” とみなす人達と直ちに対等になれます。彼らがリポジトリを公開していれば、内部の人達と同じツール・同じ手順で、プロ ジェクトの履歴のコピーや、変更の実施、作業の記録といったことを、すぐにでも行うことができます。中央集約型の場合はそれとは対 照的に、中央のサーバに対する変更コミットの権限を与えられない限り、 “読み込み専用” モードでしか使うことができません。コミッ ト権限が付与されるまでは変更の記録はできず、中央のリポジトリとの同期の際には常に手元での変更が破損する危険を抱えていま す。
分散構成管理ツールは、プロジェクトを “分裂” させ易くしてしまうため、オープンソースプロジェクトにとってある種の危険要因とな る、と言われてきました。分裂は、これ以上一緒に開発を継続できないと結論付ける原因となるような、開発グループ間での意見や特性 の相違のがある場合に発生します。両陣営は、プロジェクトのソースコードの概ね完全なコピーを持って、お互いの方向へと分かれてゆ きます。
時には、分裂した各陣営が、お互いの相違に折り合いを付ける決定をすることがあります。中央集約型の構成管理システムでは、折 り合いを付けるための技術的な処理が苦しく、大部分は手動で実施しなければなりません。誰の変更履歴が “生き残る” のかを決定した 上で、何とかして他のチームの変更をソースツリーに移植しなければなりません。この作業は通常、他方の履歴情報の一部ないし全部を 失うことになります。
分散型にとっては、分裂こそがプロジェクトを発展させる唯一の方法なのです。個々の変更は、全て潜在的な分裂点なのです。分裂 は常に発生している全く基本的な事象なので、分散構成管理は実際に分裂を上手くマージできなければならない、という点にこの考え方 の強みがあります。
全ての人の全ての作業が、常に分裂とマージの観点から組み立てられた場合、オープンソース世界が “分裂” として 言及するものは、純粋に社会的な問題となるでしょう。どちらかといえば、分散型は分裂の可能性を低下させていま す。
プロジェクト全般への緊密な統治の維持が中央集約型ツールによって得られる、と信じているために、分散型に抵抗する人もいま す。しかし、そういった期待の元で CVS ないし Subversion によるリポジトリを公開しても、無数に存在するツールによって、プロ ジェクト全体の履歴を(例え遅いとは言え)取り出し、あなたの制御の及ばない場所で再構築することができてしまいます。 “プ ロジェクト全般への緊密な統治の維持” が錯覚である一方、 So while your control in this case is illusory, you are foregoing the ability to fluidly collaborate with whatever people feel compelled to mirror and fork your history. XXXXXX
多くの商業プロジェクトは、世界中に散らばったチームが請け負っています。中央のサーバから遠く離れたメンバーは、コマンド実行の 遅さや、おそらく殆ど信頼性の無いサーバとの接続を目にすることでしょう。商業的な構成管理システムは、遠隔サイト複 製4 の追加 機能によるこれらの問題を解決しようとしていますが、通常、こういった機能は高価で保守が大変です。分散型の場合は、そもそもこう いった問題で悩む必要がありません。更に、例えばサイトごとに一台ずつという塩梅で、信頼できるサーバを複数立ち上げる ことも簡単ですので、高価で距離のあるネットワーク経路越しのリポジトリ間で、余計な通信をする必要はありませ ん。
中央集約型の構成管理システムは、相対的にスケーラビリティが低い傾向にあります。高価な中央集約システムだからといって、平 行利用する数ダースのユーザの負荷によってダウンしてしまうことは、有り得ないことではありません。繰り返しに なりますが、高負荷におけるダウンに対する典型的な対応は、高価で古臭い複製機能の利用です。分散型ツールを使 用する場合、中央サーバ – 仮に持っているとしても一台だけでしょうが – における負荷は非常に低いので、もっと大 人数のチームの要求を単一の安価なサーバで捌くことができますし、負荷分散は単にスクリプト作成の問題となりま す。
顧客の元に出て問題対応するメンバーがいる場合、分散構成管理は有益です。他のビルドからは隔離された状態で特別なビルドのた めに複数の修正を試したり、障害や退行の要因をソースの修正履歴から効果的に検索したりといったことを、客先環境で自社のネット ワークに接続すること無しに行うことができます。
Mercurial は、とりわけ構成管理システムとして良い選択をしたと言える、類を見ない特徴を持っています。
構成管理システムに慣れ親しんでいるのであれば、 Mercurial を使えるようになるのに5分も掛からない筈です。そうでない場合で も、更に数分以上は掛からないでしょう。 Mercurial のコマンドや機能群は、全体的に統一性と一貫性が保たれていますので、沢山の 例外事項ではなく、少数の一般的な方法だけを覚えておけば良いのです。
小さなプロジェクトの場合、すぐにでも Mercurial を使い始めることができるでしょう。新たな変更やブランチを生成し、変更を (同一ホストないしネットワーク越しで)持ち歩いたり、履歴参照や状態確認といった全ての操作が高速です。元来非常に高速な操作に 加えて、目に見えるオーバーヘッドが少ないために、 Mercurial は俊敏さを保ち、利用者の作業を妨げることを避けることができま す。
Mercurial の有用性は小さなプロジェクトに限定されません。数百から数千のメンバを持ち、ソースコードが数万ファイル・数百メ ガバイトに及ぶプロジェクトでも採用されています。
Mercurial の基本機能に満足できない場合でも、容易に拡張することができます。 Mercurial は処理のスクリプト化に適しており、 Python を使って綺麗に実装されていることが、「イクステンション」という形式での機能追加を容易にしています。「障害特 定の補助」から「性能向上」といった広い範囲で、評判の良い有用な多くのイクステンションが既に提供されていま す。
この先を読む前に、著者自身の経験/関心/(あえて言いますが)偏見といったものが、本節に反映せざるを得ない点をご理解くださ い。著者は、以下にあげる構成管理ツールのそれぞれを、最長で数年程度使用した経験があります。
Subversion は CVS の置き換えを目指して開発された、評判のよい構成管理ツールです。 Subversion は中央集約型の「クライアント/ サーバ」アーキテクチャを持っています。
Subversion と Mercurial は、同じ作用を持つ似たような名前のコマンドを持っているので、一方に馴染みのあるユーザは他方の用 法を容易に習得できます。これらは両方とも全ての著名な OS 上で利用可能です。
Subversion は履歴を意識したマージ機能を持っていないので、どのリビジョンのブランチ間でマージすべきかを、ユーザ自身が厳密 に指定することを強制します。この指定ができなかったり間違えたりした場合、マージにおける不必要な衝突を手動で解決する羽目にな ります。
著者がベンチマーク計測した限りでは、 Subversion の全ての構成管理操作において、 Mercurial は性能の面で相当に優位にいま す。筆者の比較によると、 Subversion の 1.4.3 版における ra_local ファイル格納(利用可能な最速のアクセス機能)と比較した場 合、2倍から6倍程度の優位性がありました。ネットワーク越しのリポジトリを必要とする、より現実的な配置の場合、 Subversion は相当に不利な状況になるでしょう。多くの Subversion コマンドはサーバとの連携が必要な上に、 Subversion は 有用な複製機能を持っていないため、少々大きめのプロジェクトの場合、サーバの性能がボトルネックとなるでしょ う。
それに加えて、ファイルの更新の検索(status)や現行版との差分表示(diff)といった、幾つかの共通操作におけるネット ワーク処理を回避するために、 Subversion は相当な格納オーバヘッドを抱え込んでいます。 Mercurial のリポジトリ がプロジェクトの完全な履歴を保持しているにも関わらず、 Subversion が抱え込む作業コピーは、 Mercurial リポ ジトリと作業領域ディレクトリのサイズと、結果としておおよそ同サイズか、あるいはそれ以上になることが多いで す。
構成管理関連のサードパーティツールに関しては、その差は徐々に埋まってはいるもの、 Mercurial と比較して、現時点では Subversion の方がより多くのサポートを受けることができます。また、 Mercurial と同様に Subversion は素晴らしいユーザマニュア ルがあります。
Subversion リポジトリから Mercurial リポジトリへの、正確で完全な変更履歴の取り込みを行うツールが幾つもありますので、古 いツールからの移行は比較的容易です。
git は、 Linux カーネルソースツリーを管理するために開発された分散構成管理ツールです。 Mercurial と同様に、その初期の設計は Monotone から影響を受けています。
git は圧倒的なまでのコマンド群を持っており、 1.5.0 版においては 139 個の独立したコマンドがあります。これらは習得が難し いとの評判です。ユーザマニュアルが存在せず、個別のコマンドに関する文書があるのみです。
性能の面では git は非常に高速です。少なくとも Linux においては、 Mercurial よりも git の方が早いケースが幾つかあります。 しかしながら本書の執筆時点では、 Windows 環境における性能(および一般的なサポート)に関しては Mercurial に及びませ ん。
Mercurial のリポジトリは保守の必要がありませんが、 git リポジトリは手動によるメタデータの “詰め直し” を頻繁に行う必要があ ります。この詰め直しをしない場合、利用領域が速やかに増加する一方で、性能が低下してしまいます。厳格且つ頻繁に詰め直しをしな い git リポジトリを沢山抱えるサーバは、バックアップの間、非常に disk-bound になりますし、結果として、日時バックアップ処理に 24時間以上を要するようになってしまった例が、いくつもあります。詰め替えによって鮮度が保たれている git リ ポジトリは、 Mercurial のリポジトリよりもわずかに小さいですが、詰め替えされていない場合はかなりの大きさで す。
git の基本部分は C で実装されています。多くの git コマンドはシェルないし Perl のスクリプトにより実装されていますが、その 品質は非常に幅が広いです。致命的とみなすべきエラーが発生している中で闇雲に処理を続けるスクリプトを、何度か見かけたことがあ ります。
CVS はおそらく世界中で最も広く使用されている構成管理ツールです。その歴史の長さと、内部的なまとまりの無さから、長い間、本質的には保守されてきませんでした。
CVS は中央集約型の「クライアント/サーバ」アーキテクチャを持っています。 CVS は関連するファイルの変更を不可分コミット へとグループ化しないため、例えば、「ある利用者による成果のコミットが、マージの必要性から部分的にしか成功しな かった場合、他の利用者からは彼の意図した変更の一部しか見ることができない」といった、 “ビルドを乱す” 行為 が容易に行えてしまいます。これは、プロジェクト履歴に対する作業の進め方にも影響します。とあるタスクの一部 として、あるメンバが行った変更を全て表示しようとした場合、関連する各ファイル(どのファイルがそうであるか を知っていれば、の話ですが)に対して行われた変更の、個々のコミットログと日付を手動で確認する必要がありま す。
CVS のタグやブランチの考え方は混乱しているため、それについて説明する気にもなれません。ファイルやディレクトリの改名が サポートされていないため、リポジトリが簡単に雑然としてしまいます。内部的な整合性をチェックする機能も持たないため、リポジト リが破損しているのか否かを判定したり、どのように破損しているのかをしることは、一般には不可能です。現存・新規のいずれのプロ ジェクトに対しても、 CVS はお薦めできません。
Mercurial は CVS のリポジトリを取り込むことができます。しかし、いくつかの注意が必要で、これは CVS のリポジトリを取り 込むことのできる、他の構成管理ツールに対しても同様です。 CVS は不可分コミットを持っておらず、ファイルシステム階層の履歴管 理も行っていないため、 CVS から履歴を正確且つ厳密に再構築することは不可能です。幾分かの推測が必要であり、改名は通常検知で きません。高度な CVS 管理の多くが手動で行われ、それ故に間違いやすいことから、 CVS からの取り込みを行うツールにとって、 破損したリポジトリからの取り込みは複数の問題に行き当たるのが常です(筆者の個人的経験から思い出せる、面白 くも無い問題の例としては、完全に偽物のタイムスタンプや、10年以上ロックされたままのファイルなどがありま す)。
Perforce は中央集約型の「クライアント/サーバ」アーキテクチャを持っていますが、クライアント側では全くキャッシュを行ってい ません。近年の構成管理ツールと異なり、編集対象となる全てのファイルに関して、 Perforce はコマンド実行によるサーバへの通知を ユーザに対して要求します。
Perforce の性能は小規模なチームでは非常に良好ですが、ユーザ数が数ダースを超える頃から急速に低下します。少々大規模な開発 向けの Perforce インストールは、ユーザアクセスによる負荷を上手く処理するために、「プロキシ」の配置が要求されま す。