単一の changeset を分割する(ファイル単位の場合)

いま working copy がこんな状態だとする。

$ hg status
M aaa
M bbb
M ccc

とりあえず aaa だけ commit しようと思って……

$ hg ci -m 'modified aaa'

あああパス指定するの忘れた。

$ hg status

bbb, ccc も changeset に取り込まれてしまった!

やりなおしたい!(あるある……というか,いまさっきやってしまった)


こんな時にも MQ は使えます。

MQ にとりこむべき changeset の revision number を知るために,とりあえず hg log してみる。

$ hg log
changeset:   1:e8d6debe7796
tag:         tip
user:        dayflower <dayflower@example.com>
date:        Tue Jun 02 15:43:50 2009 +0900
summary:     modified aaa

changeset:   0:f746ed49fd00
user:        dayflower <dayflower@example.com>
date:        Tue Jun 02 15:43:28 2009 +0900
summary:     initial import

ふむ。changeset 1 を指定すればよいのね。なので hg qimport -r 1 とやってもいいんだけど,今回の場合は最新の changeset だから tip キーワードを使って,

$ hg qimport -r tip

のようにすればよい。

で確認してみると,

$ hg qseries -s
1.diff: modified aaa

いまさっきの changeset が MQ のパッチスタックに変換された(そして適用済み)。


これで hg qpop して,patches/ ディレクトリのパッチを直接いじればいいのかなぁ……なんて思ってウェブを調べたら,そんなめんどいことはしなくてよかった。MqTutorial - Mercurial にきちんと書いてありました。


発想としては,1.diff のパッチ内容を aaa に関するものだけに修正しよう―― refresh しよう――ということになる。なので,hg qpop をせずに話をすすめます。

んで,現在のパッチスタックのパッチにどのファイルに対する変更があるのか調べてみる。

$ hg qdiff | grep '+++'
+++ b/aaa	Tue Jun 02 15:45:05 2009 +0900
+++ b/bbb	Tue Jun 02 15:45:05 2009 +0900
+++ b/ccc	Tue Jun 02 15:45:05 2009 +0900

これ他にいいやり方ないですかね。ともかく,aaabbbccc が最新パッチに含まれていることがわかった。

なので,1.diffaaa への変更内容だけ含むように refresh する。

$ hg qrefresh aaa

これで 1.diffaaa の修正履歴「だけ」を含むように更新された((今後一部 commit のアナロジーで間違えてやっちゃいそうな syntax ですな。qrefresh の使い道からすると修復不能で困ったりはしないけど。))。

パッチ群をみてみると

$ hg qseries -s
1.diff: modified aaa

適用されたままだけど,

$ hg status
M bbb
M ccc

bbbccc はパッチに含まれない。やったね!

なので,現在のパッチをもう一度 changeset に戻す。つまり hg qfinish するだけ。

$ hg qfinish -a

あいかわらず何もいわれないので不安になるけど,ステータスをみてみると,

$ hg status
M bbb
M ccc

きちんと?未 commit のままになってる。

んで,ログをみると

$ hg log
changeset:   1:6b8e35a13500
tag:         tip
user:        dayflower <dayflower@example.com>
date:        Tue Jun 02 15:43:50 2009 +0900
summary:     modified aaa

changeset:   0:f746ed49fd00
user:        dayflower <dayflower@example.com>
date:        Tue Jun 02 15:43:28 2009 +0900
summary:     initial import

aaa の修正履歴だけはまた changeset に戻ってる。すばらしい。


今回はファイル単位の changeset を分割したんだけど,修正内容の一部だけ……とかやる場合は,やはりパッチを手でいじくる必要がある(⇒ MqTutorial - Mercurial)。

このへんは git のほうがすぐれている気もする。でも Mercurial + MQ で十分満足。