Mercurial チュートリアル hginit.com の和訳 (Repository Architecture)

Mercurialリポジトリ設定に関する膨大な柔軟性を与えてくれる。結果としてマージは非常にうまく動き、あなたはそれに依存出来るようになるため、 特別な目的のリポジトリを手元に置きながらあなたの開発プロセスに適応させるといったことも可能になる。

Repository Architecture

私たちのレシピはなかなか良くなってきた。

C:\Users\joel\recipes> hg log -l 3
changeset:   13:1b03ab783b17
tag:         tip
parent:      12:f923c9049234
parent:      11:0bd396c9b89b
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 23:01:55 2010 -0500
summary:     merge

changeset:   12:f923c9049234
parent:      10:8646f8cd7154
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 22:49:31 2010 -0500
summary:     mmmmango

changeset:   11:0bd396c9b89b
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 22:46:47 2010 -0500
summary:     bananas YUM

changeset 番号をもっと近づいて見てみよう。

changeset: 13:1b03ab783b17

番号の最初の部分、13が、短くて便利だ。でもそこには一つ問題がある・・・信用できないんだ!

チームで作業する人たちが分かれて作業し、そして作業結果をマージする時に、それらの短い番号は同期されていないんだ。

だから、すべての意図や目的に対して、私は「OK, changeset 13 のリビジョンを基にリリースしよう」とは言えないんだ。だって彼らは 13 に対して異なる考えを持っているかもしれないからね。おかしな16進数の番号があるのはそのためだ。

changeset: 13:1b03ab783b17

16進数の番号は全てのリポジトリに対して一貫した値であり、決して変更されない。

OK, これで私はみんなにこう言える。「よし、今日リリースしよう!changeset 番号は1b03ab783b17! changeset に名前を付けてもいいよね?」

そう、これはあなたにも出来る。tagと呼ばれるものだ。

C:\Users\joel\recipes> hg tag Version-1.0

ログを見てみよう。

C:\Users\joel\recipes> hg log -l 2
changeset:   14:1adc88356f40
tag:         tip
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 09:38:06 2010 -0500
summary:     Added tag Version-1.0 for changeset 1b03ab783b17

changeset:   13:1b03ab783b17
tag:         Version-1.0
parent:      12:f923c9049234
parent:      11:0bd396c9b89b
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 23:01:55 2010 -0500
summary:     merge

注目して欲しいのは、タグを追加する行為というのは changeset であり、自動的に私のところにコミットされているってことだ。そして今、いつでも私がリリースしたコードのバージョンを参照したい時には1b03ab783b17の代わりに、 Version-1.0 を使うことが出来る。

CEO がリリース記念パーティのために、高そうなスパークリングワインの栓を開けて31階から降りてきた。スタンはほんのちょっとお酒を飲んだ。うん、ちょっとではないな。今まで誰もこんな事は見たことが無かった。彼はシャツを脱ぎ、彼の贅肉の無い筋肉を見せ付けて、マーケティング部門の女性たちに印象付けようとしていた。「私は照明でだって懸垂出来るんだ」と、彼は自慢していた(ここには長い蛍光灯の照明がある)。そして彼は飛び上がり、備品につかまって、そしてもちろんそれらは即座に壊れてしまった。照明は5キロ程度で天井から一組のピアノ線でぶら下げられていたが、彼の体重はどこかのうわさでは130キロくらいだ。彼は照明全体と天井タイルを壊し、いたるところでグラスと防音タイルを粉々にし、着地する時に尾骨を打ちつけて、めそめそ泣きながら安全に問題がある環境を作った会社を訴えてやると喚いた。

私たちの残りは自分のパーティションに戻り、Guac 2.0 に着手した。

guac :

* 2 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
* 2 tablespoons cilantro leaves, finely chopped
* 1 tablespoon of fresh lime or lemon juice
* 1/2 teaspoon coarse salt
* A dash of freshly grated black pepper
* 1/2 ripe tomato, seeds and pulp removed, chopped
* 1 ripe young Mango, in season.
* 1 delicious, yellow BANANA.

・・・このように編集する。

guac :

GUACAMOLE 2.0 THIS IS GOING TO BE AWESOME

* 200 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
* 2 tablespoons cilantro leaves, finely chopped
* 1 tablespoon of fresh lime or lemon juice
* 1/2 teaspoon coarse salt
* A dash of freshly grated black pepper
* 1/2 ripe tomato, seeds and pulp removed, chopped
* 1 ripe young Mango, in season.
* 1 delicious, yellow BANANA.

コミットする。

C:\Users\joel\recipes> hg com -m "more avocado flavor"

言うまでも無いが、ここにあるレシピはとても不安定なものだ。テストも何もしていないのだから。そしてある顧客が電話してきた。

「しょっぱ過ぎるよ!」と、彼はブツブツ文句を言ってきた。そしてまた、彼は version 2.0 で修正するのを待ちたくないとも言ってきた。

幸運な事に、私たちはタグを作っていた。私は hg up でリポジトリの好きなバージョンに行くことが出来る。

C:\Users\joel\recipes> hg up -r Version-1.0
1 files updated, 0 files merged, 1 files removed, 0 files unresolved

C:\Users\joel\recipes> type guac
* 2 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
...


そして今、私はこのばかばかしい塩問題を修正出来る。

guac :

* 2 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
* 2 tablespoons cilantro leaves, finely chopped
* 1 tablespoon of fresh lime or lemon juice
* 1/2 teaspoon coarse salt
* A dash of freshly grated black pepper
* 1/2 ripe tomato, seeds and pulp removed, chopped
* 1 ripe young Mango, in season.
* 1 delicious, yellow BANANA.

・・・このように編集する。

guac :

* 2 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
* 2 tablespoons cilantro leaves, finely chopped
* 1 tablespoon of fresh lime or lemon juice
* 1 grain table salt, split in half
* A dash of freshly grated black pepper
* 1/2 ripe tomato, seeds and pulp removed, chopped
* 1 ripe young Mango, in season.
* 1 delicious, yellow BANANA.

そして、

C:\Users\joel\recipes> hg diff
diff -r 1b03ab783b17 guac
--- a/guac      Thu Feb 11 23:01:55 2010 -0500
+++ b/guac      Fri Feb 12 10:44:19 2010 -0500
@@ -3,7 +3,7 @@
 * 1-2 jalapeno chiles, stems and seeds removed, minced
 * 2 tablespoons cilantro leaves, finely chopped
 * 1 tablespoon of fresh lime or lemon juice
-* 1/2 teaspoon coarse salt
+* 1 grain table salt, split in half
 * A dash of freshly grated black pepper
 * 1/2 ripe tomato, seeds and pulp removed, chopped
 * 1 ripe young Mango, in season.

C:\Users\joel\recipes> hg com -m "less salt"
created new head

Mercurial は私が新しい head を作ったと教えてくれる。今、そこには2つの head がある。私がほんの 1秒前に作業していた 2.0 の head と、今私がコミットした 1.1 の head だ。

私は1.1のタグを付けて顧客にリリースして、version 2.0 の作業に戻る事が出来る。

C:\Users\joel\recipes> hg tag -r . Version-1.1

C:\Users\joel\recipes> hg log -l 3
changeset:   17:f4220e321145
tag:         tip
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 11:17:02 2010 -0500
summary:     Added tag Version-1.1 for changeset 60ddc0122eb4

changeset:   16:60ddc0122eb4
tag:         Version-1.1
parent:      13:1b03ab783b17
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 10:44:32 2010 -0500
summary:     less salt

changeset:   15:90c349eca2e8
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 10:31:24 2010 -0500
summary:     more avocado flavor


C:\Users\joel\recipes> hg up -r 15
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

C:\Users\joel\recipes> type guac
GUACAMOLE 2.0 THIS IS GOING TO BE AWESOME

* 200 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
* 2 tablespoons cilantro leaves, finely chopped
* 1 tablespoon of fresh lime or lemon juice
* 1/2 teaspoon coarse salt
* A dash of freshly grated black pepper
* 1/2 ripe tomato, seeds and pulp removed, chopped
* 1 ripe young Mango, in season.
* 1 delicious, yellow BANANA.
...

一つだけ問題がある・・・ここには塩の修正が無いんだ。どうやって解決しよう?

C:\Users\joel\recipes> hg merge
merging .hgtags

うわー。私はタグをマージしなければならない。これは Mercurial のイラつかせるバグだ。問題というのは、タグは Mercurial ではただのファイルであって、これは .hgtags という名前なのだが、このファイルもまたバージョン管理下にあるため、時々、あなたは異なるバージョンの .hgtags を手動でマージしなければならない。この事態が起きた時にあなたがすべきことは簡単だ・・・いつだって両方のバージョンのファイルの全ての行を維持するんだ。

merging guac
0 files updated, 2 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

C:\Users\joel\recipes> hg diff guac
diff -r 90c349eca2e8 guac
--- a/guac      Fri Feb 12 10:31:24 2010 -0500
+++ b/guac      Fri Feb 12 11:32:43 2010 -0500
@@ -5,7 +5,7 @@
 * 1-2 jalapeno chiles, stems and seeds removed, minced
 * 2 tablespoons cilantro leaves, finely chopped
 * 1 tablespoon of fresh lime or lemon juice
-* 1/2 teaspoon coarse salt
+* 1 grain table salt, split in half
 * A dash of freshly grated black pepper
 * 1/2 ripe tomato, seeds and pulp removed, chopped
 * 1 ripe young Mango, in season.

C:\Users\joel\recipes> hg com -m "bringing in salt fix from 1.1"

古いタグ付けしたバージョンに戻るためのこの単純な方法は、リリースしたコードに予期していなかった小さな修正を施す時には素晴らしいものだ。実際、ほとんどのソフトウェアプロジェクトでは、いつでもこのような事が起こる。そして Mercurial は、この問題に対処するための、より健全な方法を持っている。

ちょうど1.0 以降の作業を全てやり直すところだったので、リポジトリを出荷直後の1.0に戻して、そして私はあなたに未来のバージョンに取り組むのと同時に、残っている顧客の不具合に対処するお洒落で健全なやり方を見せることが出来る。

C:\Users\joel\recipes> cd ..

C:\Users\joel> hg clone -r 14 recipes recipes-stable
requesting all changes
adding changesets
adding manifests
adding file changes
added 15 changesets with 15 changes to 2 files
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

C:\Users\joel> cd recipes-stable

C:\Users\joel\recipes-stable> hg log -l 3
changeset:   14:1adc88356f40
tag:         tip
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 09:38:06 2010 -0500
summary:     Added tag Version-1.0 for changeset 1b03ab783b17

changeset:   13:1b03ab783b17
tag:         Version-1.0
parent:      12:f923c9049234
parent:      11:0bd396c9b89b
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 23:01:55 2010 -0500
summary:     merge

changeset:   12:f923c9049234
parent:      10:8646f8cd7154
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 22:49:31 2010 -0500
summary:     mmmmango

そのアイデアというのは、一つのリポジトリで全てをやる代わりに2つのリポジトリを作るということだ。一つは stable と呼び、もう一つは dev と呼ぶことにする。

stable リポジトリは顧客にリリースした最新のメジャーバージョンのコードを持っている。あなたが緊急のバグを修正しなければならない時にはいつでも、stable でそれを行う。この例では全て 1.0 向けのパッチになる。

dev リポジトリは次のメジャー版を開発を行う場所で、2.0 になる。

1.0 をリリースしてすぐに、私はstable を dev にクローンした。

C:\Users\joel\recipes-stable> cd ..

C:\Users\joel> hg clone recipes-stable recipes-dev
updating to branch default
2 files updated, 0 files merged, 0 files removed, 0 files unresolved

今、私は2つの同一なリポジトリを持っている。

これらのリポジトリの両方の履歴は changeset 14 まで同一であるため、Mercurial ではハードリンクを使ってファイルの重複を避けている。こういった理由から hg clone 操作は速くて安価になっているので、あなたはためらわずにたくさんのクローンを作る事が出来る。

今、私たちは dev リポジトリで作業を開始した。

C:\Users\joel> cd recipes-dev

C:\Users\joel\recipes-dev> edit guac

C:\Users\joel\recipes-dev> hg diff
diff -r 1adc88356f40 guac
--- a/guac      Fri Feb 12 09:38:06 2010 -0500
+++ b/guac      Fri Feb 12 15:15:01 2010 -0500
@@ -1,4 +1,6 @@
-* 2 ripe Hass avocados (not Haas)
+GUACAMOLE 2.0 THIS IS GOING TO BE AWESOME
+
+* 200 ripe Hass avocados (not Haas)
 * 1/2 red onion, minced (about 1/2 cup)
 * 1-2 jalapeno chiles, stems and seeds removed, minced
 * 2 tablespoons cilantro leaves, finely chopped

C:\Users\joel\recipes-dev> hg commit -m "more avocado flavor"

そして、塩問題を stable リポジトリで修正した。

C:\Users\joel\recipes-dev> cd ..\recipes-stable

C:\Users\joel\recipes-stable> edit guac

C:\Users\joel\recipes-stable> hg diff
diff -r 1adc88356f40 guac
--- a/guac      Fri Feb 12 09:38:06 2010 -0500
+++ b/guac      Fri Feb 12 15:18:31 2010 -0500
@@ -3,7 +3,7 @@
 * 1-2 jalapeno chiles, stems and seeds removed, minced
 * 2 tablespoons cilantro leaves, finely chopped
 * 1 tablespoon of fresh lime or lemon juice
-* 1/2 teaspoon coarse salt
+* 1 grain table salt, split in half
 * A dash of freshly grated black pepper
 * 1/2 ripe tomato, seeds and pulp removed, chopped
 * 1 ripe young Mango, in season.

C:\Users\joel\recipes-stable> hg com -m "less salt"

タグ付けして 1.1 としてリリースしよう。

C:\Users\joel\recipes-stable> hg tag Version-1.1

そして、時折、私たちは stable から dev に修正を pull する。

C:\Users\joel\recipes-stable> cd ..\recipes-dev

C:\Users\joel\recipes-dev> hg in
comparing with c:\Users\joel\recipes-stable
searching for changes
changeset:   15:e05c954f961f
tag:         Version-1.1
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 15:28:27 2010 -0500
summary:     less salt

changeset:   16:f0e8768829ed
tag:         tip
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Fri Feb 12 15:28:40 2010 -0500
summary:     Added tag Version-1.1 for changeset e05c954f961f


C:\Users\joel\recipes-dev> hg pull
pulling from c:\Users\joel\recipes-stable
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 2 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

C:\Users\joel\recipes-dev> hg merge
merging guac
0 files updated, 1 files merged, 0 files removed, 0 files unresolved
(branch merge, don't forget to commit)

C:\Users\joel\recipes-dev> hg com -m "merge"

C:\Users\joel\recipes-dev> type guac
GUACAMOLE 2.0 THIS IS GOING TO BE AWESOME

* 200 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
* 2 tablespoons cilantro leaves, finely chopped
* 1 tablespoon of fresh lime or lemon juice
* 1 grain table salt, split in half
* A dash of freshly grated black pepper
* 1/2 ripe tomato, seeds and pulp removed, chopped
* 1 ripe young Mango, in season.
* 1 delicious, yellow BANANA.

Smoosh all ingredients together.
Serve with tortilla chips.

これが私たちがやった結果だ。

そして、もしあなたがそのおかしな図を理解出来たのなら、あなたはあなたのやり方で十分に Mercurial を理解している。この要点は結局のところ stable リポジトリのみがバグ修正を持っていて、dev リポジトリには新しいコードとバグ修正をマージしたものがあるということだ。

他にも複数のリポジトリを使うやり方がある。

  • あなたは少数の人々がある機能に対して作業するためのチーム用リポジトリを設定してもよい。 その作業が終了して機能が十分に動いたら、あなたはチームのリポジトリの変更をメイン開発リポジトリに push して、 他の人たちがそれを見ることが出来るようにする。
  • あなたはテスターのための QA リポジトリを設定してもよい。メインリポジトリに push する代わりに、 あなたはあなたのテストしたコードをQAリポジトリに push する。一度テスターに承認されれば、あなたはQAリポジトリからメイン開発リポジトリに push する。 この方法ならばメインリポジトリは常にテスト済みのコードが含まれる事になる。
  • それぞれの開発者が自分自身のリポジトリを持っているため、あなたはあなたの友人から実験的な changeset を手に入れて、 チームの他のメンバーに負担を負わせる事無しに、それをテストする事が出来る。

大規模で複雑化した組織では、あなたはこれらのテクニックを組み合わせて、お互いに pull し合えるリポジトリの束を設定できる。それぞれの機能はテストと統合を経験していくことでツリーのより上層へ引っ張り上げられていき、最後には顧客が手に入れることが出来るメインのリリース用リポジトリに新しいコードが置かれるようになる。


自己診断テスト

このチュートリアルを読んだ後であなたが理解すべきやり方は次の通りだ。

  1. 古いバージョンにタグを付けて、そこに戻る
  2. あなたのチームを"stable"と"dev"で組織化する

さて、私たちはどうにかこのチュートリアルの最後にたどり着いた。 Mercurial の全てをカバーするには至っていないが、さらに深く進むための豊富なリソースがある。 この本は全てをカバーし、完全な詳細が載っている。もしあなたが何か疑問を持ったならKiln Knowledge Exchangeを薦める。 (StackOverflow に似ているが、しかし Kiln では、Mercurial に関する質問がそちらより歓迎される。)

目次へ