Mercurial 勉強中 (6) - named branch と update -C

今回は named branch についてです。別に Mercurial を利用するうえで必須の概念ではないのですが,こいつを使うと multiple heads での changeset 間移動に習熟できますので。

ひとことまとめ

  • Multiple heads は怖くない!hg update -C で branch 間の移動も自由自在
    • ただし,update するまえに commit しといてね

準備

まず作業用のレポジトリを作ります。

% hg init

% touch 1 2

% hg ci -A -m "1, 2 added"
adding 1
adding 2

1 と 2 というファイルも追加しました。commit のオプション -A とは,commit 時に同時に addremove をかけてくれる……すなわち,未 commit のファイルを自動的に追加削除してくれる,というお役立ちオプションです。

新規 branch を切る

さて,現在の branch を確認してみます。

% hg branch
default

% hg branches
default                        0:17bcfbed3d0d

branch を明示的に設定していない状態では,default という branch になっています。また,現在 branches として default しかないことがわかります。

では,新しい geometric という branch を切ってみます。

% hg branch geometric
marked working directory as branch geometric

現在の Working copy の branch を geometric としました。

% hg branch
geometric

% hg branches
default                        0:17bcfbed3d0d

現在のbranch は geometry になりましたが,branches にはまだ default しかありません。レポジトリ側にはまだこの branch は存在してないわけです。なので commit をかけます。

% hg ci -m "geometric branch added"

% hg branches
geometric                      1:758ffd431dee
default                        0:17bcfbed3d0d (inactive)

無事 geometric という branch がレポジトリにも入りました。

ここで default branch が inactive となっているのは,default branch がそのまま geometric branch に移行したため……つまり,multiple heads になっていない,ということです。現在のレポジトリの状況を図示すると下記のようになります。


さて,この geometric branch に等比数列となるファイルを追加していきましょう。

% touch 4 8 16

% hg ci -A -m "4, 8, 16 added"
adding 16
adding 4
adding 8

% ls -F
1  16  2  4  8

4, 8, 16 というファイルを追加しました。

別の branch を切る

ここでフィボナッチ数列のために fibonacci という新しい branch を切ることにします。branch の元としては,1, 2 というファイルがある changeset まで戻ることにします。これすなわち default branch の最終状態のことですよね。

ということで update コマンドを用いて Working directory を過去の changeset まで戻します。

% hg update default
0 files updated, 0 files merged, 3 files removed, 0 files unresolved

% ls -F
1  2

無事 1, 2 のファイルがある状態まで戻りました。このように,update コマンドは changeset のリビジョン番号のみならず,branch 名,tag 名を指定することができます。


ここから fibonacci branch を切ります。geometric のときと同様です。

% hg branch fibonacci
marked working directory as branch fibonacci

さきほどの geometric の例では,ここで commit しましたが,実運用上は Working copy に変更をあたえた後に同時に commit しても構いません。なので,3, 5, 8 というファイルを追加してから commit してみます。

% touch 3 5 8

% hg ci -A -m "fibonacci branch added; 3, 5, 8 added"
adding 3
adding 5
adding 8

無事追加されました。

現在の branch, branches の状況をみてみます。

% hg branch
fibonacci

% hg branches
fibonacci                      3:65e2c33e3e95
geometric                      2:f73bb24baabb
default                        0:17bcfbed3d0d (inactive)

このように,現在の branches は,もともとの default と geometric, fibonacci となりました。また,fibonacci branch の head の changeset は 3, geometric branch の head は 2 であることがわかります。この状況を図示すると下記のようになります。

別 branch に移動する(update -C で!)

では先ほどのように update で geometric branch に移動してみましょう。

% hg update geometric
abort: update spans branches, use 'hg merge' or 'hg update -C' to lose changes

おっと,怒られてしまいました。メッセージで指摘されたように,branch をまたがる update の場合,安全確保のため abort するようになっています。merge については以前説明しました*1。今回は別 branch に移動するので,hg update -C というコマンドを使うことにします。

「lose changes」とか脅されているのが怖いですね。でも,update する前に commit してあれば怖くもなんともありません。今回はすでに commit してるので問答無用で update -C します。

% hg update -C geometric
2 files updated, 0 files merged, 2 files removed, 0 files unresolved

% ls -F
1  16  2  4  8

% hg branch
geometric

無事等比数列の世界に戻ってきました。

ふたたび fibonacci branch に戻るときも,同様に update -C します。

% hg update -C fibonacci
2 files updated, 0 files merged, 2 files removed, 0 files unresolved

% ls -F
1  2  3  5  8

さきほどのフィボナッチ数列の状態に戻っていますね。

現在の Working directory の changeset を確認する

ふたたびふたたび geometric branch に戻ります。

% hg update -C geometric
2 files updated, 0 files merged, 2 files removed, 0 files unresolved

% ls -F
1  16  2  4  8

いまは Multiple heads のはずです。実際に heads コマンドで確認してみます。

% hg heads
changeset:   3:65e2c33e3e95
branch:      fibonacci
tag:         tip
parent:      0:17bcfbed3d0d
user:        dayflower
date:        Thu Mar 13 14:50:52 2008 +0900
summary:     fibonacci branch added; 3, 5, 8 added

changeset:   2:f73bb24baabb
branch:      geometric
user:        dayflower
date:        Thu Mar 13 14:49:56 2008 +0900
summary:     4, 8, 16 added

たしかに multiple heads になっています。図示すると以下のようになります。


では,コマンドラインから現在いる場所(対応する changeset)を確認するにはどうすればいいのでしょう。tip なる概念がありましたが……

% hg tip
changeset:   3:65e2c33e3e95
branch:      fibonacci
tag:         tip
parent:      0:17bcfbed3d0d
user:        dayflower
date:        Thu Mar 13 14:50:52 2008 +0900
summary:     fibonacci branch added; 3, 5, 8 added

あくまでレポジトリの最新状態である changeset 3 が返されました。Subversion での HEAD と同じ雰囲気です。

もちろん branch コマンドでも現在の branch を確認することはできますが,Working copy がその branch の最新版(head)に相当するかどうかがわかりません。


さて。方法のひとつが parents コマンドです。

% hg parents
changeset:   2:f73bb24baabb
branch:      geometric
user:        dayflower
date:        Thu Mar 13 14:49:56 2008 +0900
summary:     4, 8, 16 added

ほかにも用途があるのですが,引数になにもつけないと Working copy の元になった changeset を表示してくれます。これすなわち「レポジトリ上の対応する changeset」のことです。

もうひとつ,ダイレクトに確認する方法が identify コマンドです。

% hg id
f73bb24baabb (geometric)

% hg id -n
2

実行すると上記のように,デフォルトでは changeset の hash id と branch を表示してくれます*2。revision number を確認するには -n をつけます。

*1:Mercurial 勉強中 (5) - conflict と multiple heads, merge - daily dayflower

*2:revision number もついでに表示してくれればいいのに