开发者

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.)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜