チュートリアル - 衝突する変更をマージする
JapaneseTutorialMerge では、私達は単純な マージ の扱い方を学びました。
Mercurial はより複雑な マージ も扱います。2 人があるファイルの同じ行を編集し、その後どうすべきかを解明しなければいけなくなるのは必ずしも珍しくはありません。こういった問題は衝突と呼ばれます; 衝突にたいして何をすべきかを解明することは、それを解決する、と呼ばれます。
まず人為的に衝突した状況を作ってみましょう。前にもしたように、my-hello を 複製することから始めましょう。
$ cd .. $ hg clone my-hello my-hello-not-cvs
今度は hello.c の出力に新しい行を加えてみましょう:
$ cd my-hello-not-cvs $ vi hello.c
main をこのように変更します:
int main(int argc, char **argv)
{
printf("hello, world!\n");
printf("sure am glad I'm not using CVS!\n");
return 0;
}
そしてこの変更を コミットします。
$ hg commit -m 'Give thanks for dodging bullet'
JapaneseTutorialFirstChange では、私達は my-hello-new-output でも 2行目の出力を加えた チェンジセットを作成したのを思いだしてください。ここにその変更を 引っ張る としたら、何が起きるでしょうか?
$ hg pull ../my-hello-new-output pulling from ../my-hello-new-output searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg update' to get a working copy)
ここまでは良いでしょう。Update してみましょう。
$ hg update abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes
JapaneseTutorialMerge のように、hg merge を実行する必要があります。しかし、ここに変化があります。Mercurial は自動的に マージすることができません、というのは各チェンジセットによって、同じソースファイルの同じ行が異なるように変更されているからです (一方は私達がコミットしたもので、もう一方は引っ張ってきたものです。その代わりに、Mercurial は手動でマージするのを助けてくれるプログラムを起動するでしょう。)
$ hg merge
この時点で何が起きるかは、コンピュータにインストールされているプログラムに依存します。もし幸運にも私達に先見の明があって、マージプログラムをインストールしていたなら、マージプログラムが立ち上がります。ここで、私達は2つの変更の間で何が衝突しているのかを確認し、それらをどうやって解決するかを決めることができます。
以下が、Linux 上の vim エディタによって表示された衝突の例です。
/* * hello.c * * Placed in the public domain by Bryan O'Sullivan * * This program is not covered by patents in the United States or other * countries. */ #include <stdio.h> int main(int argc, char **argv) { printf("hello, world!\n"); <<<<<<< /home/motoko/project/my-hello-not-cvs/hello.c.orig.197516148 printf("sure am glad I'm not using CVS!\n"); ||||||| /tmp/hello.c~base.aYR8Pf ======= printf("sure am glad I'm using Mercurial!\n"); >>>>>>> /tmp/hello.c~other.F7OpXy return 0; }
Mercurial はファイル毎の 3-way マージを使用します。これはマージ処理に 3 つの入力ファイルがあることを意味し、それらは次の通りです:
- ローカルファイル (現在のリポジトリ由来)
- 他のファイル (マージされるリポジトリ由来)
- 基本ファイル (枝分かれする前の最後のバージョン)
3-way についてのさらなる情報は、Revctrl wiki にある ThreeWayMerge を見てください。
もしマージプログラムをインストールしていないなら、テキストエディタが立ち上がり、マージする必要があるファイルを開きます。これを手で行うことは 非常に間違いを起こしやすく、退屈です。エディタを終了して hg rollback コマンドを使って Pull の影響を元に戻して、その後 マージプログラム をインストールして、その後もう1度試してみるのが最善です。
(注: Mercurial バージョン 0.9 より前では、hg update -m が hg merge の代わりに、hg undo が hg rollback の代わりに使われていました。)
(注: 不必要な hello.c.orig が残るけどどうしよう?)
いつものように、この変更をレポジトリに commit して完了です:
$ hg commit -m "Merged changes from my-hello-new-output"
このコマンドはなにも出力しないはずです。
それでは JapaneseTutorialConclusion に進んでおしまいにしましょう。