How do I split work into multiple patches with mercurial queues?
If I've been churning away at the code for a while, and forgotten to create a patch series as I go, how do I create the patch series retrospectively? So far the only thing that comes to mind is:
# Prepare and test the first batch of changes.
$ hg qrecord -m 'first batch' 1.patch
$ hg qnew -m 'stash downstream changes' stash-1.patch
$ hg qdelete -k temp-1.patch
$ make hello
cc hello.c -o hello
hello.c: In function ‘main’:
hello.c:4: error: syntax error at end of input
make: *** [hello] Error 1
$ echo '}' >> hello.c
$ make hello
cc hello.c -o hello
$ hg qrefresh
# Recover the stashed changes.
$ patch -p1 < .hg/patches/last.patch
# And around we go again!
$ hg qrecord -m 'second batch' 2.patch
$ hg qnew -m 'stash downstream changes' stash-2.patch
$ hg qdelete -k stash-2.patch
$ make hello
...
This very cumbersome approach is also hazardous. I might forget the -k
on qdelete
, at which point I'll go bash my forehead against a brick wall for several minutes, or I might include too much or too little during the 开发者_Python百科qrecord operation.
Is there a better way?
(What I'd really like is to be able to hg qpop
to just before a patch I want to split, and use a currently non-existent command, hg qunrecord
, to interactively suck changes out of the patch into my working directory. Once I'm happy with the changes, hg qnew -f
could squeeze a new patch in front of the old one.)
The MQTutorial explains how to split patches. So you could create a patch from you current work and split it into several patches.
TortoiseHg has very useful feature "Hunk Selection" in Commit dialog for kind of this work:
http://tortoisehg.bitbucket.io/manual/2.0/commit.html#change-selection
I think the crecord extension will let you do this. It gives you an interactive curses based interface where you can choose exactly what's in a commit.
Enable built-in extensions:
[extensions]
mq=
record=
shelve=
Then move MQ into working tree and split changes and remove original patch:
$ hg qpop my.patch
$ patch -p1 <.hg/patches/my.patch
$ hg qnew -i my1.patch
....
$ hg qnew -i my2.patch
....
$ hg qnew myN.patch # last without interactive stuff
$ hg qdelete --keep my.patch
Between my$i.patch
and my$((i+1)).patch
you can use hg shelve
/hg unshelve
to test if project built and pass tests on top of my$i.patch
without later changes!
If you find that something missing on this stage use hg qref
on shelved changes or hg qref -i
on unshelved changes!
See also Mercurial: move MQ patch to shelve?
First, install crecord because it is just a way way nicer way of splitting changes up.
$ hg qcrecord part1
$ hg qnew part2 # ok, slightly a lie at this point
$ hg qpop
$ echo "}" >> hello.c
$ hg qrefresh
$ hg qpush
$ hg qcrefresh # Keep just what you want in part2
$ ...
The only thing special to crecord here is the qcrefresh command. If you're not a curses fan, you can still do all of the same stuff here, just replace qcrefresh with hg qrefresh -X 're:.'
. Or hg qrefresh -I aauuuuuggghhh
if you'd prefer. (It's your "uncommit" using -X or -I.)
精彩评论