バージョン管理ツール

2010年2月17日

ソフトウェア開発者とツールについて話すと、バージョン管理ツールが最も大きな話題の一つです。バージョン管理ツールを使うようになると、どの優秀な開発者にとっても、それは生活の大きな部分を占めるようになります。バージョン管理ツールは、プロジェクトの履歴を維持するだけでなく、チームのコラボレーションの基盤となるため重要です。そのため、バージョン管理ツールに対する不満をよく耳にするのも当然です。先日公開したThoughtworksテクノロジーレーダーでは、企業が使用を検討すべきバージョン管理ツールとして、Subversionと分散バージョン管理システム(DVCS)の2つを挙げました。ここでは、バージョン管理ツールについて社内で行われた多くの議論をまとめ、その内容を詳しく説明します。

しかし、まずは少しばかりの注意が必要です。この記事は、Thoughtworks社内の同僚や社外の友人、知人との非科学的な会話の集積に基づいて執筆しました。厳密なテストや体系的な比較は行っていないため、私の他の記事と同様に、これは事例証拠に基づいています。私自身の近年の経験は、主にSubversionとMercurialですが、私の使用方法パターンはソフトウェア開発チームの典型的なものではありません。私の知り合いのほとんどは、アジャイルXPアプローチ(その名称に難色を示す人もいますが)で作業することを好み、その作業スタイルをサポートするツールを必要としています。この記事に苛立つ人もいるでしょう。その苛立ちが、私がリンクできる良質な記事につながることを願っています。

(この記事を書いた後、小規模なVCS調査を実施しましたが、私の結論が覆されることはありませんでした。)

基本的に、広く承認されているバージョン管理システムは3つあります:Subversion(svn)、GitMercurial(hg)です。

推奨ラインを下回るツール

多くのツールは、推奨ラインをクリアできません。その理由は、機能の不足または認知度の低さの2つです。

多くのツールは、Thoughtworksの社員から機能不足について常に不満の声が上がっています。(Thoughtworksの社員の性格からすると、推奨されているツールを含め、すべてのツールに何らかの不満があります。推奨ラインを下回るツールには、ほとんど不満の声が上がっています。)特に、ClearCase(IBM製)とTFS(Microsoft製)の2つには、多くの批判が寄せられています。これらのツールが多くの批判を受ける理由の一つは、クライアントサイトで非常に人気があり、多くの場合、会社の方針で使用が義務付けられていることです(最後に、それに対処するための戦略について説明します)。

VCSの使用に関する会社の方針によって、これらの問題が悪化することがよくあると言えます。私は、チームに課せられた非常に奇妙なワークフローによって、何かを成し遂げるための絶え間ないハードルとなっているという話を聞いたことがあります。VCSはこれらのワークフローを強制するツールであるため、非難の対象になりがちです。

ここでは、機能不足のツールが抱える問題について詳しく説明するつもりはありません。それは別記事のテーマです。(IBMとMicrosoftでは、この記事によってさらに不評を買っているかもしれません。)少なくとも今は、私が尊敬する開発者がこれらの製品を幅広く使用した結果、推奨していないという事実だけを述べておきます。

ツールが推奨ラインを下回るもう一つの理由は、一部のツールについてはあまりコメントを聞かないことです。これは、あまり普及していないツールの場合、使用方法を知っている、あるいは知りたいと思っている開発者を見つけるのが難しいという問題があるためです。優れたツールであっても、普及しない理由はたくさんあります。以前はPerforceについて良い評判を聞くことがありましたが、今ではSubversionはおろか、DVCSよりも優れているとは言えないという意見が主流のようです。DVCSといえば、ここで取り上げた2つ以外にも多くのDVCSが存在します。特にBazaarは、時折良い評判を聞くことがありますが、それでもGitやMercurialに比べると、耳にする機会ははるかに少ないです。

推奨ラインを下回るツールの話を終える前に、特にひどいツールについて少しだけ触れておきます。Visual Source Safe、私が呼ぶところのVisual Source Shredderです。ありがたいことに、最近はあまり見かけなくなりましたが、もし使用しているのであれば、すぐに使用をやめることを強くお勧めします。今すぐです。使いにくいだけでなく、リポジトリの破損に関する話を何度も聞いてきたので、foo.txtよりも価値のあるものを預けるのは危険です。

こうして、私の知り合いが概ね満足している3つのツールが残りました。興味深いことに、この3つすべてがオープンソースです。これらのツールから選択するには、まず集中型VCSモデルと分散型VCSモデルのどちらを選択するかを決め、DVCSを選択した場合、GitとMercurialのどちらを選択するかを決める必要があります。

分散型か集中型か

ほとんどの場合、集中型と分散型の選択は、開発チームのスキルと規律のレベルによって決まります。分散型システムはワークフローに大きな柔軟性をもたらしますが、その柔軟性は、適切に使用するだけの成熟度がなければ危険なものとなります。Subversionは、シンプルな集中リポジトリモデルを推奨し、大規模なブランチの作成を discouraged します。継続的インテグレーション(私の友人のほとんどが好む作業方法です)を使用する環境では、このモデルは reasonably well適合します。そのため、Subversionはほとんどの環境に適した選択肢となります。

DVCSはワークフローの構成に大きな柔軟性を与えますが、私の知っているほとんどの人は、依然として継続的インテグレーションで使用される共有メインラインリポジトリの概念に基づいて作業パターンを構築しています。最新のVCSには、異なるユーザーの変更をマージするためのほぼ魔法のようなツールがありますが、これらのマージは依然としてテキストのマージに過ぎません。意味的な整合性を得るためには、継続的インテグレーションが依然として必要です。そのため、DVCSを使用するチームでさえ、通常は中央のマスターリポジトリという概念を持っています。

Subversionには、最新の分散型システムと比較して、3つの大きな欠点があります。

分散型システムは常にリポジトリ全体をローカルディスクにコピーするため、リポジトリ操作は常に高速です。中央サーバーへのネットワーク呼び出しは不要です。これは、ログの参照、古いリビジョンとの差分比較、その他リポジトリ全体に関連する操作を行う場合に、顕著な違いとなります。ホームネットワークでこれが顕著であれば、リポジトリが別の場所にある場合(分散プロジェクトのように)は、大きな問題となります。

リポジトリへのネットワーク接続がない場所に出張する場合でも、分散型システムであればリポジトリで作業できます。ネットワーク接続がない飛行機の中でも、作業のチェックポイントをコミットしたり、履歴を閲覧したり、リビジョンを比較したりできます。

最後の欠点は、ツールの問題というよりも、むしろ社会的な問題です。DVCSは、実験のための迅速なブランチ作成を促します。Subversionでもブランチを作成できますが、すべてのユーザーにブランチが表示されるため、実験的な作業のためにブランチを作成することをためらう人がいます。同様に、DVCSは作業のチェックポイント作成を促します。コンパイルやテストに合格しない不完全な変更でも、ローカルリポジトリにコミットできます。これもSubversionの開発者ブランチで行うことはできますが、そのようなブランチが共有スペースにあるため、ためらう人がいます。

この最後の点は、DVCSに反対する議論にもつながります。DVCSは、無謀なブランチ作成を促し、最初は気分が良いかもしれませんが、簡単にマージの破綻につながる可能性があります。特に、フィーチャーブランチアプローチは、私が推奨しない一般的なアプローチです。前述の同様のコメントと同様に、無謀なブランチ作成は特定のツールに特有のものではないことを指摘しなければなりません。ClearCase環境でも、同じ問題について不満を言う人をよく見かけます。しかし、DVCSはブランチ作成を促すため、DVCSを適切に使用する にはチームにより多くのスキルが必要であると私が示唆する主な理由となっています。

DVCSを使いこなせるチームであっても、Subversionの方が適しているケースが1つあります。それは、共同作業する成果物がバイナリであり、VCSでマージできない場合です。たとえば、Word文書やプレゼンテーション資料などです。この場合、単一ライターチェックアウトによる悲観的ロックに戻す必要があります。そのためには、集中型システムが必要です。

GitかMercurialか

DVCSを選択する場合、どちらを選ぶべきでしょうか?MercurialとGitが最も注目されているため、私はこの2つから選択することになると考えています。そして、選択は、パワーと使いやすさ、そして、認知度とGitHubの影響力の比較に boils down します。

Gitは、そのパワーで好まれているようです。ファイルの名前変更があっても、テキストのマージを自動的かつ正確に行う、ほぼ魔法のような能力に人々は魅了されています。マージ機能を客観的に比較したテストは見たことがありませんが、主観的な意見ではGitが優勢です。

(同僚のルーカス・ワードが定義した名前変更を介したマージは、次のシナリオを説明しています。私がFoo.csをBar.csに名前変更し、ルーカスがFoo.csにいくつかの変更を加えます。マージすると、彼の変更は正しくBar.csに適用されます。GitとMercurialの両方が、これを処理します。)

多くの人にとって、Gitの最大の欠点は、しばしば不可解なコマンドとメンタルモデルでした。ベン・バトラー・コールは、それを美しく表現しました。「そこには驚くほど強力なものがうごめいていて、私がどうすればいいのかを知っていれば、私が求めることは基本的に何でもしてくれるだろう」。批判的な人にとっては、Gitには発見可能性が欠けています。つまり、見かけのデザインからその機能を徐々に推測する能力です。Gitの支持者は、これはGitが他のVCSとは異なるメンタルモデルを使用しているためであり、Gitを理解するには、VCSに関する知識をより多く unlearn する必要があると主張しています。いずれにせよ、Gitは内部構造を学ぶことを楽しむ人に魅力的で、Mercurialはバージョン管理を行いたいだけの人に魅力的であるようです。

GitHubの影響力は、ここで重要です。Gitに懐疑的な人でさえ、GitHubはプロジェクトコラボレーションに最適な場所であると評価しています。Mercurialの equivalent であるBitbucketは、同じような愛情を抱かせることはありません。しかし、その差を埋め始める可能性のある他のサイト、特にGoogle CodeとMicrosoftのCodeplexがあります。(CodeplexでのMercurialの利用は非常に心強いと思います。Microsoftは、しばしば、補完的なオープンソース製品との連携が不十分であると批判されています。オープンソースホスティングサイトでMercurialを使用していることは、非常に心強い兆候です。)

歴史的に、git は Windows での動作が貧弱で、推奨できないほどでした。しかし現在は、msysgit を使用し、cygwin を使用しない限り、状況は改善されています。私たちの現在の見解では、msysgit は Mercurial との比較を Windows において問題ではなくするのに十分なほど優れています。

一般的に、git は Mercurial よりもブランチ処理が優れていると考えられています。特に、実験やチェックポイントのための短命のブランチに適しています。Mercurial は、別々のリポジトリディレクトリの高速クローンやキューパッチなどの他のメカニズムを推奨していますが、git のブランチングはよりシンプルで優れたモデルです。

Mercurial は、大きなバイナリファイルを扱う際に問題があるようです。私の一般的な提案は、そのようなものは通常 subversion で管理する方が良いということです。しかし、別々に管理するには数が少なすぎる場合は、Mercurial がそれらによって停止してしまう可能性があります。

複数の VCS

複数の VCS を同時に使用することには、多くの場合利点があります。これは一般的に、チームが使用したいものよりも機能の低い VCS を使用する必要がある場合です。

私たちが頻繁に遭遇するケースは、機能不足の VCS(通常は ClearCase)の企業標準が存在する一方で、効率的に作業したい場合です。その場合、日々のチーム作業には別の VCS を使用し、必要な場合にのみ企業の VCS にコミットすることで成功を収めてきました。そのため、チームの VCS は 1 人あたり 1 日に複数回のコミットを確認しますが、企業の VCS は 1 ~ 2 週間に 1 回のコミットを確認します。多くの場合、それは企業の管理者が望んでいることです。歴史的に、私たちはローカルの VCS として svn を使用してこれを行ってきましたが、将来的にはローカルのフロントエンドとして DVCS を使用する可能性が高くなります。

この二重使用のシナリオは、人々がローカルでは git を使用し、共有 svn システムにコミットする git-svn でも一般的です。Git-svn は、mercurial よりも git を好むもう1つの理由です。ローカル DVCS を使用することは、ネットワークの停止や帯域幅の問題が集中型 VCS から離れたサイトを麻痺させる可能性のある、リモートサイトでの作業に特に役立ちます。

多くのチームは、特に企業の VCS によって多くの企業の儀式が強制されている場合、このデュアル VCS 作業スタイルの恩恵を受けることができます。デュアル VCS を使用すると、多くの場合、ローカル開発チームと企業のコントローラーの両方を満足させることができます。なぜなら、VCS に対する彼らの動機はしばしば異なるからです。

最後に

ここでツールについて多くのことを述べましたが、多くの場合、より大きな違いを生むのはプラクティスとワークフローであることを忘れないでください。ツールは確かに優れたプラクティスのセットを使用するのをはるかに容易にすることができますが、最終的には、環境に効果的な作業方法を使用するのは人次第です。私は、継続的インテグレーションを使用して迅速に統合される多くの小さな変更を可能にするアプローチが好きです。CI を使用した貧弱なツールの方が、CI を使用しない優れたツールよりも優れています。