{i} This page appears to contain material that is no longer relevant. Please help improve this page by updating its content.

Merging Patches

The MqExtension can help you rebase your patches via three-way merging. This feature is still under active development, but the general usage will be updated here as things change.

The most common scenario is a patch queue against upstream revision A which you want to update to upstream revision B. The basic model is to fully apply your current patch queue on top of revision A, and then use those changesets for merging any patches that don't apply properly to the new upstream revision. Merging is only used when a patch applies with fuzz or rejects against the new base.

Example:

# check that there are no uncommitted (not qrefreshed) changes.
# The steps below discard any such changes without any warning, at least in Mercurial 1.0.2
hg status

# push all of your patches.  This gives you changesets
# in the hg repo to merge with.
hg qpush -a

# use hg qsave to make a copy of the patch directory
# it prints the name of the backup directory used
hg qsave -e -c

# pull the new upstream revision.  Do not use pull -u
hg pull

# update to the new upstream head.  Do not use update -m
hg update -C tip

# use hg qpush -m to merge each patch
hg qpush -m -a

# after verifying the results, pop the old patch queue and
# delete the backups.  Since hg qpush -a -m created merge
# sets, we need to get rid of them with hg qpop first
#
# patches.N was printed by hg qsave
#
hg qpop -a
hg qpop -a -n patches.N
rm -rf .hg/patches.N

Command Detail

hg qsave -e -c does three things. First it pushes a save changeset onto the top of your current queue. This records the state of the status and series file in the save changeset. It can be removed with qpop, qrestore or strip.

hg qsave -c will make a copy of the patch directory. By default this will be named .hg/patches.N, where N is an integer >= 1. if .hg/patches.1 already exists, .hg/patches.2 will be used, etc. hg qsave -c -n name will use .hg/name as the destination for the copy.

hg qsave -e will delete .hg/patches/status after creating the save changeset. This file holds information about which patches are applied, so deleting it makes it look as though the patch queue is empty.

hg qpush -m triggers a three-way merge if the patch fails to apply. A saved patch queue is used to find the changesets for merging. qpush defaults to the .hg/patches.N directory with the highest number when trying to find a saved patch queue. hg qpush -m -n name can be used to specify the name of the save directory.

During qpush -m, each patch in .hg/patches/series is applied normally. If there are fuzz or rejects, the save queue status file is checked for a patch with the same name. A three way merge is done with the corresponding changeset, and a new patch is generated based on the result. The resulting merge changeset is then stripped away and the new patch is applied in the current queue.

At the end of the process described above, your repository will have one extra head from the old patch queue, and a copy of the old patch queue will be in .hg/patches.N. The extra head can be removed with hg qpop -a -n patches.N or hg strip and you can delete .hg/patches.N when you no longer need it as a backup.

Questions

See Also

MqMerge (last edited 2012-05-08 14:13:37 by 46-116-136-37)