[PATCH 06 of 11] ?copies: update _checkcopies to work in a rotated DAG (issue4028)

Gábor STEFANIK Gabor.STEFANIK at nng.com
Wed Oct 5 08:04:13 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: Wednesday, October 5, 2016 2:02 PM
> To: mercurial-devel at mercurial-scm.org
> Subject: [PATCH 06 of 11] ?copies: update _checkcopies to work in a rotated
> DAG (issue4028)
>
> # HG changeset patch
> # User G?bor Stefanik <gabor.stefanik at nng.com> # Date 1475588213 -7200
> #      Tue Oct 04 15:36:53 2016 +0200
> # Node ID fc6190cdbebfab4a3cff72f213018fcc30b8f25c
> # Parent  bc8729a69d10d61498712d5dab773918f1edcde0
> ?copies: update _checkcopies to work in a rotated DAG (issue4028)

Ouch! Even worse encoding errors.

>
> This introduces a distinction between "merge common ancestor" 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.
>
> To correctly find copies in case of a graft, we need to take both the merge CA
> and the topological CA into account, and track any renames between them in
> reverse.
>
> Special care must be taken about the case where the merge CA lies not
> between the topological CA and the source, but outside it (typically between
> the topological CA and the destination).
> This is handled using the remoteca parameter; it would be possible to have
> _checkcopies itself detect this, but it's quite expensive and also guaranteed
> not to change between multiple _checkcopies invocations in the same
> mergecopies call, so it's better to check it there, and pass to _checkcopies as
> a parameter.
>
> diff -r bc8729a69d10 -r fc6190cdbebf mercurial/copies.py
> --- a/mercurial/copies.pyMon Oct 03 13:29:59 2016 +0200
> +++ b/mercurial/copies.pyTue Oct 04 15:36:53 2016 +0200
> @@ -345,10 +345,12 @@
>      bothnew = sorted(addedinm1 & addedinm2)
>
>      for f in u1u:
> -        _checkcopies(c1, f, m1, m2, ca, limit, diverge, copy1, fullcopy1)
> +        _checkcopies(c1, f, m1, m2, ca, ca, False, limit, diverge, copy1,
> +                     fullcopy1)
>
>      for f in u2u:
> -        _checkcopies(c2, f, m2, m1, ca, limit, diverge, copy2, fullcopy2)
> +        _checkcopies(c2, f, m2, m1, ca, ca, False, limit, diverge, copy2,
> +                     fullcopy2)
>
>      copy = dict(copy1.items() + copy2.items())
>      movewithdir = dict(movewithdir1.items() + movewithdir2.items()) @@ -
> 373,8 +375,10 @@
>                        % "\n   ".join(bothnew))
>      bothdiverge, _copy, _fullcopy = {}, {}, {}
>      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, ca, ca, False, limit, bothdiverge, _copy,
> +                     _fullcopy)
> +        _checkcopies(c2, f, m2, m1, ca, ca, False, 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 @@ -
> 454,7 +458,8 @@
>
>      return copy, movewithdir, diverge, renamedelete
>
> -def _checkcopies(ctx, f, m1, m2, ca, limit, diverge, copy, fullcopy):
> +def _checkcopies(ctx, f, m1, m2, ca, tca, remoteca, limit, diverge, copy,
> +                 fullcopy):
>      """
>      check possible copies of f from m1 to m2
>
> @@ -462,7 +467,9 @@
>      f = the filename to check
>      m1 = the source manifest
>      m2 = the destination manifest
> -    ca = the changectx of the common ancestor
> +    ca = the changectx of the common ancestor, overridden on graft
> +    tca = topological common ancestor for graft-like scenarios
> +    remoteca = True if ca is outside tca::ctx, False otherwise
>      limit = the rev number to not search beyond
>      diverge = record all diverges in this dict
>      copy = record all non-divergent copies in this dict @@ -475,6 +482,8 @@
>      """
>
>      ma = ca.manifest()
> +    mta = tca.manifest()
> +    backwards = ca != tca and not remoteca and f in ma
>      getfctx = _makegetfctx(ctx)
>
>      def _related(f1, f2, limit):
> @@ -520,15 +529,26 @@
>              continue
>          seen.add(of)
>
> -        fullcopy[f] = of # remember for dir rename detection
> +        # remember for dir rename detection
> +        if backwards:
> +            fullcopy[of] = f # grafting backwards through renames
> +        else:
> +            fullcopy[f] = of
>          if of not in m2:
>              continue # no match, keep looking
>          if m2[of] == ma.get(of):
>              return # no merge needed, quit early
>          c2 = getfctx(of, m2[of])
> -        cr = _related(oc, c2, ca.rev())
> +        cr = _related(oc, c2, tca.rev())
>          if cr and (of == f or of == c2.path()): # non-divergent
> -            copy[f] = of
> +            if backwards:
> +                copy[of] = f
> +            elif of in ma:
> +                copy[f] = of
> +            elif remoteca: # special case: a <- b <- a -> b "ping-pong" rename
> +                copy[of] = f
> +                del fullcopy[f]
> +                fullcopy[of] = f
>              return
>
>      if of in ma:
> diff -r bc8729a69d10 -r fc6190cdbebf tests/test-graft.t
> --- a/tests/test-graft.tMon Oct 03 13:29:59 2016 +0200
> +++ b/tests/test-graft.tTue Oct 04 15:36:53 2016 +0200
> @@ -427,8 +427,8 @@
>    $ hg graft 3 --log -u foo
>    grafting 3:4c60f11aa304 "3"
>    warning: can't find ancestor for 'c' copied from 'b'!
> -  $ hg log --template '{rev} {parents} {desc}\n' -r tip
> -  14 1:5d205f8b35b6  3
> +  $ hg log --template '{rev}:{node|short} {parents} {desc}\n' -r tip
> + 14:0c921c65ef1e 1:5d205f8b35b6  3
>    (grafted from 4c60f11aa304a54ae1c199feb94e7fc771e51ed8)
>
>  Resolve conflicted graft
> @@ -620,7 +620,7 @@
>    date:        Thu Jan 01 00:00:00 1970 +0000
>    summary:     2
>
> -  changeset:   14:f64defefacee
> +  changeset:   14:0c921c65ef1e
>    parent:      1:5d205f8b35b6
>    user:        foo
>    date:        Thu Jan 01 00:00:00 1970 +0000


More information about the Mercurial-devel mailing list