Rebasing unapplied patches after refresh

Roland Kaufmann rlndkfmn+nabble at gmail.com
Tue Dec 1 05:35:24 CST 2009


I would like recommendations on how to best handle editing of patches,
using the queues extension. I am currently at version 1.3.1, but can 
upgrade if necessary.

I consider myself fairly familiar with the concept of queues, but I 
find retrospect editing of patches to be a cumbersome, convoluted 
process, indicating that there is perhaps a better way.

To illustrate my point, consider the workflow below specified as a 
series of shell commands. Points (1) and (2) just build up a queue:

#-----------------------------------------------------------------------
# (1) setup a new repository containing just an empty file
dir=$(mktemp -d) && mkdir -p $dir && pushd $dir
hg init && hg qinit
touch hello.txt && hg addremove && hg commit -m "Initial commit"

# (2) write some code, making checkpoints as we go
echo hello > hello.txt && hg qnew -m "Greeting" -f hello
echo hello world > hello.txt && hg qnew -m "Recipient" -f world
echo hello, world\! > hello.txt && hg qnew -m "Punctuation" -f punct
#-----------------------------------------------------------------------

Now, let's say that I am interested in fixing up some patches (before 
submitting), for instance capitalize letters, and pretend that the 
fixes were in there from the beginning (i.e. not show up in history).

If I understand <http://mercurial.selenic.com/wiki/MqMergePatches> 
correctly, points (3a)--(6a) is the normal way of handling this:

#-----------------------------------------------------------------------
# (3a) save baseline for all patches; all must be applied first
hg qpush -a
qp=$(hg log --template="{rev}" -r qparent)
hg qsave -c -e

# (4a) wtf! now directory and queue state is not synchronized
# roll the directory back to where the queue appearently is
hg update -C $qp

# (5a) fixup one of the patches
hg qgo hello
echo Hello > hello.txt
hg qref

# (6a) this will enter the 3-way tool to let us merge, although
# we'll have to do repeated merges if the tool is line-based
hg qpush -m -a
#-----------------------------------------------------------------------

This leaves both the old patches and the merge trails in the history, 
as is evidenced by `hgtk log`; the main culprit seems to be that qsave 
disconnects the queue from the contents of the working directory.

A little more cleanup is also required to get back to the point where 
we started:

#-----------------------------------------------------------------------
# (7a) clear all fixed patches out of the way
hg qgo hello && hg qpop

# (8a) remove all extranous commits that are the result of merge
hg strip -n $(echo $qp + 1 | bc)

# (9a) back where we started
hg qgo hello
#-----------------------------------------------------------------------

An alternate procedure without using queues, but rather based on 
multiple heads and rebase would be this:

#-----------------------------------------------------------------------
# (3b) goto the changeset that we want to edit and finalize,
# noting the revision numbers of the commit
hg qgo hello && hg qfin -a
hello=$(hg log --template="{rev}" -r tip)
next=$(echo $hello + 1 | bc)

# (4b) finalize all the rest of the changesets as well
hg qpush -a && hg qfin -a

# (5b) back again to the changeset in question and do the actual edit
hg update -C -r $hello
echo Hello > hello.txt && hg commit -m "(edit)"

# (6b) graft all further changesets onto this new head
hg rebase -s $next -d tip

# (7b) import back into a queue. no way of getting original names?
hg qimp -r $hello:tip

# (8b) merge the two edits into one patch
hg qgo $hello.diff && hg qfold $next.diff && hg qref -m "Greeting"
#-----------------------------------------------------------------------

But in this scenario, the names of the patches are lost and the commit 
message must be entered twice. It also seems just as error-prone as 
the first one.

Obviously, qpush needs to have access to the parent of all the
remaining patches in order to do the merge, but this could perhaps be 
stacked away right before the refresh is done and then a 3-way merge 
be done immediately with this and the new as the parent.

Those more familiar with the code than I, are you aware of any 
pitfalls that could cause problems of such a `qrefresh --rebase` 
approach?

Yours sincerely,

   Roland Kaufmann
-- 
View this message in context: http://old.nabble.com/Rebasing-unapplied-patches-after-refresh-tp26590414p26590414.html
Sent from the Mercurial mailing list archive at Nabble.com.



More information about the Mercurial mailing list