[PATCH 05 of 12 v2] copies: make _checkcopies handle simple renames in a rotated DAG

Gábor STEFANIK Gabor.STEFANIK at nng.com
Sun Oct 16 11:22:20 EDT 2016



>


--------------------------------------------------------------------------
This message, including its attachments, is confidential. For more information please read NNG's email policy here:
http://www.nng.com/emailpolicy/
By responding to this email you accept the email policy.


-----Original Message-----
> From: Mercurial-devel [mailto:mercurial-devel-bounces at mercurial-scm.org]
> On Behalf Of Gábor Stefanik
> Sent: Sunday, October 16, 2016 5:16 PM
> To: mercurial-devel at mercurial-scm.org
> Subject: [PATCH 05 of 12 v2] copies: make _checkcopies handle simple
> renames in a rotated DAG
>
> # HG changeset patch
> # User Gábor Stefanik <gabor.stefanik at nng.com> # Date 1476317034 -7200
> #      Thu Oct 13 02:03:54 2016 +0200
> # Node ID 48dba8d1f7fab137418bfbb833c3096969eec934
> # Parent  1f91343556e7cef7a71edf512b02f7e0f09d5e9b
> copies: make _checkcopies handle simple renames in a rotated DAG
>
> This introduces a distinction between "merge base" and "topological
> common ancestor". During a regular merge, these two are identical. Graft,
> however, performs a merge in a rotated DAG, where the merge common
> ancestor will not be a common ancestor at all in the original DAG.

That was meant to read "merge base will not be".

>
> To correctly find copies in case of a graft, we need to take both the merge
> base and the topological CA into account, and track any renames between
> them in reverse. Fortunately we can detect this in advance, see comment in
> the code about "backwards".
>
> This patch only supports finding non-divergent renames contained entirely
> between the merge base and the topological CA. Further patches are coming
> to support more complex cases.
>
> (Pierre-Yves David was involved in the cleanup of this patch.)
>
> diff -r 1f91343556e7 -r 48dba8d1f7fa mercurial/copies.py
> --- a/mercurial/copies.pyThu Oct 13 02:03:49 2016 +0200
> +++ b/mercurial/copies.pyThu Oct 13 02:03:54 2016 +0200
> @@ -374,10 +374,10 @@
>      bothnew = sorted(addedinm1 & addedinm2)
>
>      for f in u1u:
> -        _checkcopies(c1, f, m1, m2, base, limit, data1)
> +        _checkcopies(c1, f, m1, m2, base, tca, limit, data1)
>
>      for f in u2u:
> -        _checkcopies(c2, f, m2, m1, base, limit, data2)
> +        _checkcopies(c2, f, m2, m1, base, tca, limit, data2)
>
>      copy = dict(data1['copy'].items() + data2['copy'].items())
>      fullcopy = dict(data1['fullcopy'].items() + data2['fullcopy'].items()) @@ -
> 405,8 +405,8 @@
>                  'diverge': bothdiverge,
>                 }
>      for f in bothnew:
> -        _checkcopies(c1, f, m1, m2, base, limit, bothdata)
> -        _checkcopies(c2, f, m2, m1, base, limit, bothdata)
> +        _checkcopies(c1, f, m1, m2, base, tca, limit, bothdata)
> +        _checkcopies(c2, f, m2, m1, base, tca, limit, bothdata)
>      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 @@ -
> 521,7 +521,7 @@
>      except StopIteration:
>          return False
>
> -def _checkcopies(ctx, f, m1, m2, base, limit, data):
> +def _checkcopies(ctx, f, m1, m2, base, tca, limit, data):
>      """
>      check possible copies of f from m1 to m2
>
> @@ -530,6 +530,7 @@
>      m1 = the source manifest
>      m2 = the destination manifest
>      base = the changectx used as a merge base
> +    tca = topological common ancestor for graft-like scenarios
>      limit = the rev number to not search beyond
>      data = dictionary of dictionary to store copy data. (see mergecopies)
>
> @@ -540,6 +541,17 @@
>      """
>
>      mb = base.manifest()
> +    # Might be true if this call is about finding backward renames,
> +    # This happens in the case of grafts because the DAG is then rotated.
> +    # If the file exists in both the base and the source, we are not looking
> +    # for a rename on the source side, but on the part of the DAG that is
> +    # traversed backwards.
> +    #
> +    # In the case there is both backward and forward renames (before and
> after
> +    # the base) this is more complicated as we must detect a divergence. This
> +    # is currently broken and hopefully some later code update will make that
> +    # work (we use 'backwards = False' in that case)
> +    backwards = base != tca and f in mb
>      getfctx = _makegetfctx(ctx)
>
>      of = None
> @@ -554,7 +566,11 @@
>              continue
>          seen.add(of)
>
> -        data['fullcopy'][f] = of # remember for dir rename detection
> +        # remember for dir rename detection
> +        if backwards:
> +            data['fullcopy'][of] = f # grafting backwards through renames
> +        else:
> +            data['fullcopy'][f] = of
>          if of not in m2:
>              continue # no match, keep looking
>          if m2[of] == mb.get(of):
> @@ -562,9 +578,11 @@
>          c2 = getfctx(of, m2[of])
>          # c2 might be a plain new file on added on destination side that is
>          # unrelated to the droids we are looking for.
> -        cr = _related(oc, c2, base.rev())
> +        cr = _related(oc, c2, tca.rev())
>          if cr and (of == f or of == c2.path()): # non-divergent
> -            if of in mb:
> +            if backwards:
> +                data['copy'][of] = f
> +            elif of in mb:
>                  data['copy'][f] = of
>              return
>
> _______________________________________________
> 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