[PATCH STABLE] graft: support grafting across renames (issue4028)

Augie Fackler raf at durin42.com
Wed Jul 27 09:14:50 EDT 2016


On Mon, Jul 25, 2016 at 01:16:32PM -0500, Gábor Stefanik wrote:
> # HG changeset patch
> # User Gábor Stefanik <gabor.stefanik at nng.com>
> # Date 1469470573 -7200
> #      Mon Jul 25 20:16:13 2016 +0200
> # Branch stable
> # Node ID 395d3fa2ac89fad199c99cc137bf801502292325
> # Parent  9c2cc107547fd701a7604349632f2f590366f17c
> graft: support grafting across renames (issue4028)

Can you construct a test? This feels like the sort of thing that is very likely to regress.

>
> Graft performs a merge with a false common ancestor, which must be taken into
> account when tracking renames. Compute the real common ancestor in this case,
> and track renames between the real and false common ancestors in reverse.
>
> diff --git a/mercurial/copies.py b/mercurial/copies.py
> --- a/mercurial/copies.py
> +++ b/mercurial/copies.py
> @@ -327,13 +327,22 @@
>          return {}, {}, {}, {}
>      repo.ui.debug("  searching for copies back to rev %d\n" % limit)
>
> +    # graft gives us a false common ancestor, we need to find a real one
> +    true_ca = ca
> +    if not (ca.descendant(c1) and ca.descendant(c2)):
> +        true_ca = c1.ancestor(c2)
> +
>      m1 = c1.manifest()
>      m2 = c2.manifest()
> -    ma = ca.manifest()
> +    ma = true_ca.manifest()
>
> -    copy1, copy2, = {}, {}
> +    copy1, copy2 = {}, {}
> +    copy1a, copy2a = {}, {}
> +    copy1b, copy2b = {}, {}
>      movewithdir1, movewithdir2 = {}, {}
>      fullcopy1, fullcopy2 = {}, {}
> +    fullcopy1a, fullcopy2a = {}, {}
> +    fullcopy1b, fullcopy2b = {}, {}
>      diverge = {}
>
>      # find interesting file sets from manifests
> @@ -343,10 +352,18 @@
>      bothnew = sorted(addedinm1 & addedinm2)
>
>      for f in u1:
> -        checkcopies(c1, f, m1, m2, ca, limit, diverge, copy1, fullcopy1)
> +        checkcopies(c1, f, m1, m2, ca, limit, diverge, copy1a, fullcopy1a)
> +        checkcopies(c1, f, m1, m2, true_ca, limit, diverge, copy1b, fullcopy1b)
> +        copy1 = dict((set(copy1a.items()) & set(copy1b.items())) |
> +            (set([(y, x) for (x, y) in copy1a.items()])-
> +             set([(y, x) for (x, y) in copy1b.items()])))
>
>      for f in u2:
> -        checkcopies(c2, f, m2, m1, ca, limit, diverge, copy2, fullcopy2)
> +        checkcopies(c2, f, m2, m1, ca, limit, diverge, copy2a, fullcopy2a)
> +        checkcopies(c2, f, m2, m1, true_ca, limit, diverge, copy2b, fullcopy2b)
> +        copy2 = dict((set(copy2a.items()) & set(copy2b.items())) |
> +            (set([(y, x) for (x, y) in copy2a.items()])-
> +             set([(y, x) for (x, y) in copy2b.items()])))
>
>      copy = dict(copy1.items() + copy2.items())
>      movewithdir = dict(movewithdir1.items() + movewithdir2.items())
> @@ -373,6 +390,8 @@
>      for f in bothnew:
>          checkcopies(c1, f, m1, m2, ca, limit, bothdiverge, _copy, _fullcopy)
>          checkcopies(c2, f, m2, m1, ca, limit, bothdiverge, _copy, _fullcopy)
> +        checkcopies(c1, f, m1, m2, true_ca, limit, bothdiverge, _copy, _fullcopy)
> +        checkcopies(c2, f, m2, m1, true_ca, limit, bothdiverge, _copy, _fullcopy)
>      for of, fl in bothdiverge.items():
>          if len(fl) == 2 and fl[0] == fl[1]:
>              copy[fl[0]] = of # not actually divergent, just matching renames
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel


More information about the Mercurial-devel mailing list