[PATCH 0 of 1] Add qpush --exact

Greg Ward greg-hg at gerg.ca
Fri Nov 19 12:56:12 CST 2010


On Thu, Nov 18, 2010 at 2:51 PM, Matt Mackall <mpm at selenic.com> wrote:
> You qpush or import a patch with a --try-magical-merge flag
> The patch code finds the parent revision P in the patch
> If that revision is present:
>  remember current revision as T
>  update to patch parent
>  apply patch
>  update T --force-ancestor P
>  commit patch

Coincidentally, I had a chance to try out something like this in real
life the other day.  In this case, I had a developer who needed to
backport four existing changesets to an older branch.  We typically
use "hg diff | hg patch --no-commit -" for this sort of thing --
transplant is inappropriate for us because we always need to test
backports before committing them.  In this case, applying patches
resulted in lots of conflicts and .rej files, so he wanted a better
way.

Here's what we ended up doing (where R1, R2, R3, and R4 are the four
changesets being backported:

  hg update p1(R1)
  hg diff -c R1 | hg patch --no-commit -
  hg diff -c R2 | hg patch --no-commit --force -
  hg diff -c R3 | hg patch --no-commit --force -
  hg diff -c R4 | hg patch --no-commit --force -

Note that R1 == p1(R2) and R2 == p1(R3), so the first three patches
are guaranteed to succeed.  R4 came a bit later in history, so there
was a risk of conflicts -- but we got lucky.

Now we need to update to T, the target revision (aka tip of the target
branch).  But simply doing

  hg update T

failed with "abort: crosses branches".  So we had to backup to the
common ancestor:

  hg debugancestor . T
  hg update <ancestor>

This invoked several file merges.  Luckily, kdiff3 handled them all
without unsolved conflicts.  We still had to review the merges, but
everything was good.  Now merge again by updating forward to the tip
of the target branch:

  hg update T

And go through another round of file merges.  Again, kdiff3 got it
right, but we checked its work carefully.

And then he had to build, test, and commit.

Bottom line: it worked; we effectively did a transplant/collapse with
3-way merging, but the "abort: crosses branches" error forced us to
update/merge twice.  In this case, it was moderately annoying, but if
there had been real conflicts it would be been more annoying.

Greg


More information about the Mercurial-devel mailing list