単一の 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 <[email protected]> date: Tue Jun 02 15:43:50 2009 +0900 summary: modified aaa changeset: 0:f746ed49fd00 user: dayflower <[email protected]> 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
これ他にいいやり方ないですかね。ともかく,aaa
,bbb
,ccc
が最新パッチに含まれていることがわかった。
なので,1.diff
を aaa
への変更内容だけ含むように refresh する。
$ hg qrefresh aaa
これで 1.diff
は aaa
の修正履歴「だけ」を含むように更新された((今後一部 commit のアナロジーで間違えてやっちゃいそうな syntax ですな。qrefresh
の使い道からすると修復不能で困ったりはしないけど。))。
パッチ群をみてみると
$ hg qseries -s 1.diff: modified aaa
適用されたままだけど,
$ hg status M bbb M ccc
bbb
と ccc
はパッチに含まれない。やったね!
なので,現在のパッチをもう一度 changeset に戻す。つまり hg qfinish
するだけ。
$ hg qfinish -a
あいかわらず何もいわれないので不安になるけど,ステータスをみてみると,
$ hg status M bbb M ccc
きちんと?未 commit のままになってる。
んで,ログをみると
$ hg log changeset: 1:6b8e35a13500 tag: tip user: dayflower <[email protected]> date: Tue Jun 02 15:43:50 2009 +0900 summary: modified aaa changeset: 0:f746ed49fd00 user: dayflower <[email protected]> date: Tue Jun 02 15:43:28 2009 +0900 summary: initial import
aaa
の修正履歴だけはまた changeset に戻ってる。すばらしい。
今回はファイル単位の changeset を分割したんだけど,修正内容の一部だけ……とかやる場合は,やはりパッチを手でいじくる必要がある(⇒ MqTutorial - Mercurial)。
このへんは git のほうがすぐれている気もする。でも Mercurial + MQ で十分満足。