[PATCH 2 of 4 V2] copies: refactor checkcopies() into a top level method
Augie Fackler
raf at durin42.com
Tue May 7 10:25:57 CDT 2013
On Mon, May 06, 2013 at 08:14:48PM -0700, Durham Goode wrote:
> # HG changeset patch
> # User Durham Goode <durham at fb.com>
> # Date 1367430261 25200
> # Wed May 01 10:44:21 2013 -0700
> # Node ID 9557401c5bab0a37d2e6eceb1fd13c66a75463f0
> # Parent 672183bf736b045705760066ef102a0a4cb52cca
> copies: refactor checkcopies() into a top level method
SGTM. Looks reasonable here.
>
> This moves checkcopies() out of mergecopies() and makes it a top level
> function in the copies module. This allows extensions to override it.
> For
> example, I'm developing a filelog replacement that doesn't have rev numbers
> so all the rev number dependent implementation here needs to be replaced
> by the extension.
Ooh. That posted anyplace I can follow along? That's relevant to my interests.
>
> No logic is changed in this commit.
>
> diff --git a/mercurial/copies.py b/mercurial/copies.py
> --- a/mercurial/copies.py
> +++ b/mercurial/copies.py
> @@ -222,65 +222,8 @@
> fullcopy = {}
> diverge = {}
>
> - def related(f1, f2, limit):
> - # Walk back to common ancestor to see if the two files originate
> - # from the same file. Since workingfilectx's rev() is None it messes
> - # up the integer comparison logic, hence the pre-step check for
> - # None (f1 and f2 can only be workingfilectx's initially).
> -
> - if f1 == f2:
> - return f1 # a match
> -
> - g1, g2 = f1.ancestors(), f2.ancestors()
> - try:
> - f1r, f2r = f1.rev(), f2.rev()
> -
> - if f1r is None:
> - f1 = g1.next()
> - if f2r is None:
> - f2 = g2.next()
> -
> - while True:
> - f1r, f2r = f1.rev(), f2.rev()
> - if f1r > f2r:
> - f1 = g1.next()
> - elif f2r > f1r:
> - f2 = g2.next()
> - elif f1 == f2:
> - return f1 # a match
> - elif f1r == f2r or f1r < limit or f2r < limit:
> - return False # copy no longer relevant
> - except StopIteration:
> - return False
> -
> - def checkcopies(f, m1, m2):
> - '''check possible copies of f from m1 to m2'''
> - of = None
> - seen = set([f])
> - for oc in ctx(f, m1[f]).ancestors():
> - ocr = oc.rev()
> - of = oc.path()
> - if of in seen:
> - # check limit late - grab last rename before
> - if ocr < limit:
> - break
> - continue
> - seen.add(of)
> -
> - fullcopy[f] = of # remember for dir rename detection
> - if of not in m2:
> - continue # no match, keep looking
> - if m2[of] == ma.get(of):
> - break # no merge needed, quit early
> - c2 = ctx(of, m2[of])
> - cr = related(oc, c2, ca.rev())
> - if cr and (of == f or of == c2.path()): # non-divergent
> - copy[f] = of
> - of = None
> - break
> -
> - if of in ma:
> - diverge.setdefault(of, []).append(f)
> + def _checkcopies(f, m1, m2):
> + checkcopies(ctx, f, m1, m2, ca, ma, limit, diverge, copy, fullcopy)
>
> repo.ui.debug(" searching for copies back to rev %d\n" % limit)
>
> @@ -295,9 +238,9 @@
> % "\n ".join(u2))
>
> for f in u1:
> - checkcopies(f, m1, m2)
> + _checkcopies(f, m1, m2)
> for f in u2:
> - checkcopies(f, m2, m1)
> + _checkcopies(f, m2, m1)
>
> renamedelete = {}
> renamedelete2 = set()
> @@ -386,3 +329,64 @@
> break
>
> return copy, movewithdir, diverge, renamedelete
> +
> +def checkcopies(ctx, f, m1, m2, ca, ma, limit, diverge, copy, fullcopy):
> + '''check possible copies of f from m1 to m2'''
> +
> + def _related(f1, f2, limit):
> + # Walk back to common ancestor to see if the two files originate
> + # from the same file. Since workingfilectx's rev() is None it messes
> + # up the integer comparison logic, hence the pre-step check for
> + # None (f1 and f2 can only be workingfilectx's initially).
> +
> + if f1 == f2:
> + return f1 # a match
> +
> + g1, g2 = f1.ancestors(), f2.ancestors()
> + try:
> + f1r, f2r = f1.rev(), f2.rev()
> +
> + if f1r is None:
> + f1 = g1.next()
> + if f2r is None:
> + f2 = g2.next()
> +
> + while True:
> + f1r, f2r = f1.rev(), f2.rev()
> + if f1r > f2r:
> + f1 = g1.next()
> + elif f2r > f1r:
> + f2 = g2.next()
> + elif f1 == f2:
> + return f1 # a match
> + elif f1r == f2r or f1r < limit or f2r < limit:
> + return False # copy no longer relevant
> + except StopIteration:
> + return False
> +
> + of = None
> + seen = set([f])
> + for oc in ctx(f, m1[f]).ancestors():
> + ocr = oc.rev()
> + of = oc.path()
> + if of in seen:
> + # check limit late - grab last rename before
> + if ocr < limit:
> + break
> + continue
> + seen.add(of)
> +
> + fullcopy[f] = of # remember for dir rename detection
> + if of not in m2:
> + continue # no match, keep looking
> + if m2[of] == ma.get(of):
> + break # no merge needed, quit early
> + c2 = ctx(of, m2[of])
> + cr = _related(oc, c2, ca.rev())
> + if cr and (of == f or of == c2.path()): # non-divergent
> + copy[f] = of
> + of = None
> + break
> +
> + if of in ma:
> + diverge.setdefault(of, []).append(f)
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at selenic.com
> http://selenic.com/mailman/listinfo/mercurial-devel
More information about the Mercurial-devel
mailing list