分散バージョン管理入門 (イラスト入り)

Kalid Azad、 2007 年 10 月 15 日、 原文 (original post) はてなブックマークへ追加 はてなブックマーク - 分散バージョン管理入門 (イラスト入り) Bookmark this on Delicious

従来のバージョン管理は、ファイルをバックアップ・追跡・同期するのに役立った。 分散バージョン管理を使うと、変更内容を共有するのが楽になる。 さぁ、両方の長所を活かすんだ。簡単なマージと一括管理されたリリースを。

分散だって? これまでのバージョン管理で何がまずいの?

別に…。 さっ、気を取り戻したければ、 バージョン管理へのビジュアルガイド(英語) を読んで。 もちろん、「古くさい」システムを使っているとバカにする人もいるだろう。 けれど、私はそれで全然かまわないと思う。 どんなバージョン管理システム(VCS)を使うにしても、プロジェクトにとっては前向きな一歩なんだから。

集中型バージョン管理システムは 1970 年頃に現れた。 その頃プログラマーには、シンクライアントと “big iron” と称されたメインフレームがあった。 (当時で贅沢な 8 ビットが 1 バイト のマシンが好きになれないなんてことがあるだろうか?)

集中型は単純で、まず最初に考案されたのがこれだ。 みんなが一ヶ所にチェックイン・チェックアウトする。 これは、本の上に落書きできるようになった図書館みたいなもんだ。

このモデルでは、 バックアップ・取り消し・同期については上手くいくけど、 複数人で変更点をマージ・ブランチするには向いていない。 プロジェクトが大きくなるにつれて、機能をブロックに分割し、 隔離した状態で開発やテストを行い、変更は緩やかにメインラインへマージしたくなるだろう。 けれど、ブランチが厄介なもんだから、現実には新機能は巨大なチェックインになってしまう。 これでは変更内容が間違っていたと分かっても、問題に対処し解決するのは困難だ。

もちろん、集中型システムでも以前からマージは「可能」だ。けれど、簡単ではない。 自分でマージを追跡して、同じ変更を繰り返してしまわないようにする必要があるんだ。 分散型システムはブランチとマージを楽にしてくれる。分散型はそれに頼っているからね。

ちょっと図をいくつか

他のチュートリアルでは、具体的なテキストコマンドをたっぷり用意しているけど、ここではイメージを話そう。 少し気分を戻して、開発者は典型的な VCS を使っていて、中央リポジトリへアクセスするとしよう。

全員が同期を取ってからメイントランクへチェックインする。 Sue は soup を、 Joe は juice を、 Eve は eggs を追加する。

Sue の変更は、メインへ入るまで他の人が目にすることはない。 まぁ、理論上 Sue は別ブランチを作って、他の人に変更をテストしてもらうことができなくはないけれど、 従来の VCS でそうするのは面倒だ。

分散バージョン管理システム (DVCS)

分散モデルでは、開発者には自分専用のリポジトリがある。 Sue の変更は彼女のローカルリポジトリに存在し、 必要に応じて Joe や Eve と共有できる。

けれど、リングリーダー無しでは大混乱してしまわないかな? いいや、 必要なら全員が共通リポジトリへ変更を送りつける(push)ようにすればいい。 上の中央リポジトリのようにね。 このフランケンシュタイン・リポジトリには Sue と Joe と Eve の変更が入っている。

分散バージョン管理は、もっと別の名前のほうが良かったと思う。 例えば、「独立」、「連合」、「ピアツーピア(P2P)」みたいな。 「分散」という言葉からは分散コンピューティングを連想してしまうし、 そこでは作業はグリッドマシン間で分割される。 (SETI@home の信号探索や たんぱく質の折り畳み のように。)

DVCS は Seti@home のようなものではない。各ノードは完全に独立しており、 共有するかしないかは自由だ。(Seti では結果を送り返さなくちゃならない。)

主な概念を 5 分で

基本をここで。もし興味を持ったなら、パッチ理論についての 本(英語) がある。

コア概念

新しい用語

主なメリット

主なデメリット

Mercurial クイックスタート

Mercurial は高速かつ分かりやすい DVCS だ。ニックネームは hg で、これは水銀(Mercury)の元素記号から取られた。

cd project
hg init                                (リポジトリをここに作成)
hg add list.txt                        (ファイルを追跡開始)
hg commit -m "Added file"              (ファイルをローカルリポジトリへチェックイン)
hg log                                 (履歴を見る ... GUID が振られている)

チェンジセット:   0:55bbcb7a4c24
ユーザ:           Kalid@kazad-laptop
日付:             Sun Oct 14 21:36:18 2007 -0400
要約:             Added file

[ファイルを編集]
hg revert list.txt                 (直前のバージョンへ戻す)

hg tag v1.0                        (このバージョンをタグづけ)
[ファイルを編集]
hg update -C v1.0                  (以前のタグづけされたバージョンへ「更新(update)」 ... -C はローカルコピーを強制的に上書きする)

Mercurial がディレクトリを初期化すると、このようになる。

ここにあるのは、

この記事の分散リポジトリ例では、 Sue、 Joe、 Eve にそれぞれ自分のリポジトリがあって、 その中に独自のリビジョン履歴がある。

更新とマージを理解する

DVCS を学ぶ時に、いくつか勘違いしそうになったことがある。 まず、更新が数ステップを経るということ。

次に、変更に応じて、 更新(update)とマージ(merge)を使い分けること。

DVCS でいとも簡単にブランチが現れマージされるということを、 私はまだはっきり理解できていない。

このケースでは、 (+Soup) と (+Juice) が共通の親(「Milk」だけを含むリスト) に対する変更であるため、マージが必要だ。 Joe がファイルをマージすると、 Sue はいつもの「pull と update」を実行するだけで、 Joe から連結されたファイルを取得できる。 彼女が自分の手で再度マージする必要はない。

Mercurial ではこのようにする。

hg incoming ../another-dir  (pull 待ちの変更をチェック)
hg pull ../another-dir      (変更をダウンロード)

hg update                   (変更を実際に適用...)
hg merge                    (... または、必要に応じてマージ)

hg commit                   (マージしたファイルをチェックイン ... ブランチを結合)

そう、「pull-merge-commit」サイクルは長い。運良く、 Mercurial には一連のコマンドをひとつにしたショートカットがある。 これは複雑そうに見えるけれど、 Subversion でマージを手作業で扱うよりはずっと簡単だ。

マージはたいてい自動だ。 衝突が見つかっても、大体はすぐに解決される。 Mercurial はすべての変更について親子関係を追跡しているんだ (さっきのマージされたリスト<訳注: 「Milk Juice Soup」のこと>には親が 2 つある)。 「ヘッド」 — つまり各ブランチの最新の変更についても同様だ。マージ前には 2 つヘッドがあり、マージ後ひとつになる。

分散型プロジェクトをまとめる

分散型プロジェクトをまとめ上げる方法をひとつ示そう。

Sue と Joe と Eve は共通のブランチへチェックインする。 ちょっとした「仲間うちビルド(buddy build)」については、互いにパッチをやり取りする。 ねぇ、ちょっと、このパッチを試してくんない? 実験版ブランチへ push する前にちゃんと動くか確認しておきたいんだ。

その後、メンテナーは変更をレビューし、実験版ブランチから安定版(stable)ブランチへ pull するだろう。 このブランチに最新リリースがあるんだ。 分散 VCS は、変更を隔離しつつも、集中型システムのような「単一ソース」を提供するのに便利だ。 開発モデルは様々で、「pull のみ」(メンテナーが何を取り込むか決定する Linux 型開発モデル) から、「共用 push」(集中型システムのように振る舞う)まで多種多様だ。分散 VCS は、 プロジェクトの運用方法に柔軟性をもたらしてくれるんだ。

最後に実践と痛烈な酷評を

私は DVCS 初心者だけど、これまでのところ身につけたことに満足している。私は SVN を好きで使っているけど、 それでもマージの手軽さに出会うことは実に「楽しい」。 私の提案としては、 Subversion から始めて、チームでの協力作業の要点を理解した後、 分散モデルを試してみるのがよいだろう。適切にレイアウトすることで、 DVCS は集中型システムでできること全てをこなせるし、その上、手軽なマージの恩恵を受けられるんだ。

オンラインの資料

注目はココ:

さぁ、がんばって、宗教戦争に気をつけよう。どんな tip や提案でも、自由にどうぞ。

翻訳: 西原 佑哉 、 2010 年 2 月 7 日 、 原文 (original post)