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

時にはマージが衝突することもある。普段ならこれを修正するのは簡単だが、それを解決する必要があったり、複数の head を持っていたりすることもあるだろう。 一体誰が複数の head を望むのだろうか?

Merging

バージョン管理で重要な事の一つは、同じコードベースでたくさんの人たちの作業を連携させられる事だ。

ローズと私の両方がグアカモーのレシピを変更したい場合を想像してほしい。ローズはアボガドの品質を改良した。 彼女は始める前に、中央サーバから最新の変更を全て pull し、最新の状態にした。

C:\Users\rose\recipes> hg pull
pulling from http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
(run 'hg update' to get a working copy)

C:\Users\rose\recipes> hg up
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

編集する。

guac :

* 2 ripe avocados
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 habanero chiles, stems and seeds removed, minced
…

・・・このように変更する。

guac :

* 2 ripe Hass avocados (not Haas)
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 habanero chiles, stems and seeds removed, minced
…

彼女は変更をコミットして、中央リポジトリに push する。

C:\Users\rose\recipes> hg diff
diff -r 549d45f24c37 guac
--- a/guac      Thu Feb 11 17:07:41 2010 -0500
+++ b/guac      Thu Feb 11 17:10:40 2010 -0500
@@ -1,4 +1,4 @@
-* 2 ripe avocados
+* 2 ripe Hass avocados (not Haas)
 * 1/2 red onion, minced (about 1/2 cup)
 * 1-2 habanero chiles, stems and seeds removed, minced
 * 2 tablespoons cilantro leaves, finely chopped

C:\Users\rose\recipes> hg com -m "better avocados"

C:\Users\rose\recipes> hg push
pushing to http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files


同時に、私はそのファイルの違う箇所を変更する。
guac :

* 2 ripe avocados
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 habanero chiles, stems and seeds removed, minced
…

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

guac :

* 2 ripe avocados
* 1/2 red onion, minced (about 1/2 cup)
* 1-2 jalapeno chiles, stems and seeds removed, minced
…

私はコミット出来るが、しかし私は中央リポジトリに push することは出来ない。

C:\Users\joel\recipes> hg diff
diff -r 549d45f24c37 guac
--- a/guac      Thu Feb 11 17:07:41 2010 -0500
+++ b/guac      Thu Feb 11 17:12:09 2010 -0500
@@ -1,6 +1,6 @@
 * 2 ripe avocados
 * 1/2 red onion, minced (about 1/2 cup)
-* 1-2 habanero chiles, stems and seeds removed, minced
+* 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

C:\Users\joel\recipes> hg com -m "better chile"

C:\Users\joel\recipes> hg push
pushing to http://joel.example.com:8000/
searching for changes
abort: push creates new remote heads!
(did you forget to merge? use push -f to force)


これは多分、Mercurial で最も不便なエラーメッセージだ。ここで言うべき内容はこうだ。

C:\Users\joel\recipes> hg push
pushing to http://joel.example.com:8000/
searching for changes

ジャン!!! リポジトリにはあなたがまだ持っていない変更があります。
push しないで下さい。まず最新の変更を pull して、それらをマージしてください。

実際にやってみよう。

C:\Users\joel\recipes> hg pull
pulling from http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

何が到着したか不思議かな?調べるには hg log -P . コマンドが重宝する。

C:\Users\joel\recipes> hg log -P .
changeset:   9:44aefdeef9e0
tag:         tip
parent:      7:549d45f24c37
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 17:10:48 2010 -0500
summary:     better avocados

なるほど、ローズの最近の変更だ。私のリポジトリには現時点で何が起こるだろうか?

C:\Users\joel\recipes> hg heads
changeset:   9:44aefdeef9e0
tag:         tip
parent:      7:549d45f24c37
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 17:10:48 2010 -0500
summary:     better avocados

changeset:   8:bf5854ca20f7
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 17:12:23 2010 -0500
summary:     better chile


C:\Users\joel\recipes> hg parent
changeset:   8:bf5854ca20f7
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 17:12:23 2010 -0500
summary:     better chile

複数の head だ。原則的には、私のリポジトリはこんな感じだ。

2つの head はわかる?この事態はローズが彼女の変更を作った時点で発生した。彼女は changeset 7 で作業していたし、私が変更を作ったのも changeset 7 だからだ。だから今、マージが必要だ。(決して消極的な声ではない!)私にはマージが必要だ。

C:\Users\joel\recipes> 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> hg log -l 4
changeset:   10:8646f8cd7154
tag:         tip
parent:      8:bf5854ca20f7
parent:      9:44aefdeef9e0
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 21:51:26 2010 -0500
summary:     merge

changeset:   9:44aefdeef9e0
parent:      7:549d45f24c37
user:        Rose Hillman <rose@example.com>
date:        Thu Feb 11 17:10:48 2010 -0500
summary:     better avocados

changeset:   8:bf5854ca20f7
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 17:12:23 2010 -0500
summary:     better chile

changeset:   7:549d45f24c37
parent:      5:d8b5146ab630
parent:      6:470aea67ee96
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 17:07:41 2010 -0500
summary:     undo thing from the past

マージコマンド hg merge は2つの head を結合する。その時、その結果を私の作業中のディレクトリに残す。コミットするわけではない。私にはマージした結果が正しい事をチェックするチャンスが与えられている。

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
* 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

Smoosh all ingredients together.
Serve with tortilla chips.

This recipe is really good served with QUESO.

QUESO is Spanish for "cheese," but in Texas,
it's just Kraft Slices melted in the microwave
with some salsa from a jar. MMM!

正しいように思える。アボガドはハスで、チリペッパーはジャラペノだ。だから私は続けて commit し、サーバに push する。

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

C:\Users\joel\recipes> hg push
pushing to http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files

私は2つの changeset を push している。私のジャラペノの変更と、それをマージしたもので、それ自身が changeset だ。

2つの変更で衝突が無かった事に注目してほしい。結果としてローズと私はレシピの他の部分を作業し続けている。つまりマージは超簡単なんだ。これはもっとも一般的な場合だが、大部分の組織では、それぞれのプログラマはコードの別々の部分にアサインされる。

時には、あなたは誰も仕事を率先してやりたがらないような機能不全を起こした組織で働く事もあるだろう。これは、突然に、そして度々、プログラミングスタッフに対して説明の無い悲しみを引き起こす。これは防ぎようがない。兆候には次のようなものがある。プログラマが彼ら自身を風呂場から締め出す、プログラマが彼ら自身をサーバ室か締め出す、高い離職率、彼らが彼らのパーティションで声を押し殺して泣く、突然軍事クラスのアサルトライフルの発砲音が鼓膜の中で繰り返される。

しかし、最高のマネージメントと健康管理のある組織だったとしても、時にはマージの衝突も起こる。そして Mercurial はマージしている人々に衝突の解決を要求する。それではどのようになるのか見てみよう。

まず・・・私がローズにジャラペノの変更を伝えたいとしよう。

C:\Users\rose\recipes> hg in
comparing with http://joel.example.com:8000/
searching for changes
changeset:   9:bf5854ca20f7
parent:      7:549d45f24c37
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 17:12:23 2010 -0500
summary:     better chile

changeset:   10:8646f8cd7154
tag:         tip
parent:      9:bf5854ca20f7
parent:      8:44aefdeef9e0
user:        Joel Spolsky <joel@joelonsoftware.com>
date:        Thu Feb 11 21:51:26 2010 -0500
summary:     merge


C:\Users\rose\recipes> hg pull
pulling from http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files
(run 'hg update' to get a working copy)

C:\Users\rose\recipes> hg up
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

では、gen-yoo-ine の衝突があった時に私たちに何が起こるか見てみよう。私たちはお互いに材料をちょっとずついじくりまわした。

私はバナナを加えた。
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

Smoosh all ingredients together.
Serve with tortilla chips.

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 delicious, yellow BANANA.

Smoosh all ingredients together.
Serve with tortilla chips.

私は最初にバナナの変更をチェックインした。

C:\Users\joel\recipes> hg diff
diff -r 8646f8cd7154 guac
--- a/guac      Thu Feb 11 21:51:26 2010 -0500
+++ b/guac      Thu Feb 11 22:46:27 2010 -0500
@@ -6,6 +6,7 @@
 * 1/2 teaspoon coarse salt
 * A dash of freshly grated black pepper
 * 1/2 ripe tomato, seeds and pulp removed, chopped
+* 1 delicious, yellow BANANA.

 Smoosh all ingredients together.
 Serve with tortilla chips.

C:\Users\joel\recipes> hg com -m "bananas YUM"

C:\Users\joel\recipes> hg push
pushing to http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files

そしてローズは、なんと、ま っ た く 同 じ 行 に マ ン ゴ ー を 付け加えた。
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

Smoosh all ingredients together.
Serve with tortilla chips.

・・・トマトが早摘みマンゴーになった。

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.

Smoosh all ingredients together.
Serve with tortilla chips.

"熟れた早摘みの"マンゴーだ、実際は。

C:\Users\rose\recipes> hg diff
diff -r 8646f8cd7154 guac
--- a/guac      Thu Feb 11 21:51:26 2010 -0500
+++ b/guac      Thu Feb 11 22:49:26 2010 -0500
@@ -6,6 +6,7 @@
 * 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.

 Smoosh all ingredients together.
 Serve with tortilla chips.

C:\Users\rose\recipes> hg com -m "mmmmango"

この時、私が先に変更を push したので、ローズがマージをすることになる。ハハ!

C:\Users\rose\recipes> hg pull
pulling from http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 1 changesets with 1 changes to 1 files (+1 heads)
(run 'hg heads' to see heads, 'hg merge' to merge)

C:\Users\rose\recipes> hg merge

そして突然、コンフリクトが検出されて、あなたの母親でも大好きになりそうなくらいによく出来ていて一目瞭然なユーザインタフェースのグラフィカルなマージコンフリクト解決ツールが立ち上がる。近頃の一般的なマージコンフリクト解決ツールはKDiff3で、ローズの場合には以下のように見える。

KDiff3 には4つの枠がある。上部左がオリジナルファイル、上部中央は彼女のバージョン、上部右は私のバージョンだ。下部の枠はコンフリクトを解決したマージ済みのファイルをローズが作るためのエディタだ。

コンフリクトの修正は、それぞれのコンフリクトを選択して解決するのとほとんど同じことである。ローズは夢中になって、バナナ・マンゴー・グアカマロは悪く無いものと決めた。

ところで、ローズがデートするようだって話したっけ?先日、彼女がデニス・フランツにちょっと似てる男と出かけるのを見た。彼女はここ数年で最も機嫌がよいように見えた。

ローズは彼女の変更を保存して、KDiff3を終了した。

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

C:\Users\rose\recipes> hg diff
diff -r f923c9049234 guac
--- a/guac      Thu Feb 11 22:49:31 2010 -0500
+++ b/guac      Thu Feb 11 23:01:45 2010 -0500
@@ -7,6 +7,7 @@
 * 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.

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

C:\Users\rose\recipes> hg push
pushing to http://joel.example.com:8000/
searching for changes
adding changesets
adding manifests
adding file changes
added 2 changesets with 2 changes to 1 files

そしてコンフリクトは解決した。

一つだけ覚えておいてほしい。あなたは誰かのスケジュールでマージをしてはいけない。あなたはあなたが望めばいつでも hg pull をしてもよいし、もしコンフリクトをマージする気にならないのならあなたが作業を続けるのは自由だし、そしてコミットは、幸運な事に、マージについて考える暇がある時に行う事が出来る。

自己診断テスト

ここまで読んであなたが理解すべきやり方は以下のとおりだ。

  1. 他の人たちと一緒に同じコードベースで作業する
  2. 彼らの変更を取得する
  3. あなたの変更を push する
  4. 時々現れるコンフリクトをマージする
  5. プログラマの憂鬱の原因を突き止める

次はリポジトリアーキテクチャについて話そう。

目次へ