Mecurialのブランチ名を変更する

MercurialはGitと異なり一度作成したブランチを削除できない仕様だ。そのため、ブランチ名を変更することが基本的に許されていない。 だが、MQ拡張を使うとブランチ名を変更できる。
# pushしていなくて、他のブランチからの干渉(マージ等)がない場合に限る

例えば、次のような歴史を築いていたとしよう。

$ hg glog
@  チェンジセット:   4:9775fad84de8
|  ブランチ:         topic
|  タグ:             tip
|  親:               2:e938e86a55c4
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:25:10 2011 +0900
|  要約:             added foo
|
| o  チェンジセット:   3:ae8709c095fd
| |  親:               1:a7338d78342d
| |  ユーザ:           yoppi
| |  日付:             Sat Mar 26 12:24:45 2011 +0900
| |  要約:             added hoge
| |
o |  チェンジセット:   2:e938e86a55c4
|/   ブランチ:         topic
|    ユーザ:           yoppi
|    日付:             Sat Mar 26 12:24:30 2011 +0900
|    要約:             added foo.txt
|
o  チェンジセット:   1:a7338d78342d
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:23:55 2011 +0900
|  要約:             added hoge
|
o  チェンジセット:   0:1b3a9c75737d
   ユーザ:           yoppi
   日付:             Sat Mar 26 12:23:36 2011 +0900
   要約:             initial commit

defaultブランチで開発を続けてrev2で新機能を追加するため'topic'ブランチを作っている。しかし、'topic'という名前をやめて'feature'としたほうが良かったと思いブランチ名を変更しようとする。
このときに、変更したいブランチ(topic)の一連のコミットをMQでパッチ化しよう。

$ hg qimport -r 4 -r 2

これでtopicブランチのコミットがパッチ化される

$ hg qseries
2.diff
4.diff

では、topicブランチのルートにあたるrev2へと移動しよう。

$ hg qgoto 2
4.diff の適用解除
適用中の最上位パッチは 2.diff です
$ hg glog
o  チェンジセット:   3:ae8709c095fd
|  タグ:             tip
|  親:               1:a7338d78342d
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:24:45 2011 +0900
|  要約:             added hoge
|
| @  チェンジセット:   2:e938e86a55c4
|/   ブランチ:         topic
|    タグ:             2.diff
|    タグ:             qbase
|    タグ:             qtip
|    ユーザ:           yoppi
|    日付:             Sat Mar 26 12:24:30 2011 +0900
|    要約:             added foo.txt
|
o  チェンジセット:   1:a7338d78342d
|  タグ:             qparent
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:23:55 2011 +0900
|  要約:             added hoge
|
o  チェンジセット:   0:1b3a9c75737d
   ユーザ:           yoppi
   日付:             Sat Mar 26 12:23:36 2011 +0900
   要約:             initial commit

現在有効になっているパッチがrev2のコミットであることがglogから読み取れる。この状態で、おもむろに.hg/branche を編集する。

$ vim .hg/branch

このファイルには現在のブランチ名が1行記述されているので、それを'feature'に変更して保存しよう。ただ、この時点では有効になっていないので、パッチをrefreshしよう。

$ hg qrefresh
$ hg glog
@  チェンジセット:   3:16e6dd2ef5bb
|  ブランチ:         feature
|  タグ:             2.diff
|  タグ:             qbase
|  タグ:             qtip
|  タグ:             tip
|  親:               1:a7338d78342d
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:24:30 2011 +0900
|  要約:             added foo.txt
|
| o  チェンジセット:   2:ae8709c095fd
|/   ユーザ:           yoppi
|    日付:             Sat Mar 26 12:24:45 2011 +0900
|    要約:             added hoge
|
o  チェンジセット:   1:a7338d78342d
|  タグ:             qparent
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:23:55 2011 +0900
|  要約:             added hoge
|
o  チェンジセット:   0:1b3a9c75737d
   ユーザ:           yoppi
   日付:             Sat Mar 26 12:23:36 2011 +0900
   要約:             initial commit

チェンジセットが2から3へ変更されているが、これはパッチを再適用すると発生してしまう。なぜなら、別のチェンジセットとみなされてしまうからだ。ただ、本質的にはその変更は前のままで、2.diffのパッチであることにはかわらない。
これでブランチ名をtopicからfeatureへ変更できた。あとは、残りのパッチも適用してパッチの編集を終了しよう。

$ hg qpush 2.diff
$ hg glog
@  チェンジセット:   4:999a9a5dcf51
|  ブランチ:         feature
|  タグ:             4.diff
|  タグ:             qtip
|  タグ:             tip
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:25:10 2011 +0900
|  要約:             added foo
|
o  チェンジセット:   3:16e6dd2ef5bb
|  ブランチ:         feature
|  タグ:             2.diff
|  タグ:             qbase
|  親:               1:a7338d78342d
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:24:30 2011 +0900
|  要約:             added foo.txt
|
| o  チェンジセット:   2:ae8709c095fd
|/   ユーザ:           yoppi
|    日付:             Sat Mar 26 12:24:45 2011 +0900
|    要約:             added hoge
|
o  チェンジセット:   1:a7338d78342d
|  タグ:             qparent
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:23:55 2011 +0900
|  要約:             added hoge
|
o  チェンジセット:   0:1b3a9c75737d
   ユーザ:           yoppi
   日付:             Sat Mar 26 12:23:36 2011 +0900
   要約:             initial commit
$ hg qfinish -a
$ hg glog
@  チェンジセット:   4:999a9a5dcf51
|  ブランチ:         feature
|  タグ:             tip
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:25:10 2011 +0900
|  要約:             added foo
|
o  チェンジセット:   3:16e6dd2ef5bb
|  ブランチ:         feature
|  親:               1:a7338d78342d
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:24:30 2011 +0900
|  要約:             added foo.txt
|
| o  チェンジセット:   2:ae8709c095fd
|/   ユーザ:           yoppi
|    日付:             Sat Mar 26 12:24:45 2011 +0900
|    要約:             added hoge
|
o  チェンジセット:   1:a7338d78342d
|  ユーザ:           yoppi
|  日付:             Sat Mar 26 12:23:55 2011 +0900
|  要約:             added hoge
|
o  チェンジセット:   0:1b3a9c75737d
   ユーザ:           yoppi
   日付:             Sat Mar 26 12:23:36 2011 +0900
   要約:             initial commit

ブランチ名をかえたい場合はブランチを切った直後の場合が多く、ブランチが未成熟の場合はこのようにMQ拡張を使って変更できる。