compat: drop 4.3 monkey patch of `copies.mergecopies`
authorPierre-Yves David <pierre-yves.david@octobus.net>
Mon, 19 Nov 2018 01:52:45 +0000
changeset 4259 bccd5c2786ba
parent 4258 697ec7c2f325
child 4260 cd0c331c430a
compat: drop 4.3 monkey patch of `copies.mergecopies`
hgext3rd/evolve/compat.py
--- a/hgext3rd/evolve/compat.py	Mon Nov 19 01:45:34 2018 +0000
+++ b/hgext3rd/evolve/compat.py	Mon Nov 19 01:52:45 2018 +0000
@@ -466,256 +466,8 @@
 
     return copy, movewithdir, diverge, renamedelete, dirmove
 
-# code imported from Mercurial core at 4.3 + patch
-def fixoldmergecopies(repo, c1, c2, base):
-
-    from mercurial import pathutil
-
-    # avoid silly behavior for update from empty dir
-    if not c1 or not c2 or c1 == c2:
-        return {}, {}, {}, {}, {}
-
-    # avoid silly behavior for parent -> working dir
-    if c2.node() is None and c1.node() == repo.dirstate.p1():
-        return repo.dirstate.copies(), {}, {}, {}, {}
-
-    # Copy trace disabling is explicitly below the node == p1 logic above
-    # because the logic above is required for a simple copy to be kept across a
-    # rebase.
-    if repo.ui.configbool('experimental', 'disablecopytrace'):
-        return {}, {}, {}, {}, {}
-
-    # In certain scenarios (e.g. graft, update or rebase), base can be
-    # overridden We still need to know a real common ancestor in this case We
-    # can't just compute _c1.ancestor(_c2) and compare it to ca, because there
-    # can be multiple common ancestors, e.g. in case of bidmerge.  Because our
-    # caller may not know if the revision passed in lieu of the CA is a genuine
-    # common ancestor or not without explicitly checking it, it's better to
-    # determine that here.
-    #
-    # base.descendant(wc) and base.descendant(base) are False, work around that
-    _c1 = c1.p1() if c1.rev() is None else c1
-    _c2 = c2.p1() if c2.rev() is None else c2
-    # an endpoint is "dirty" if it isn't a descendant of the merge base
-    # if we have a dirty endpoint, we need to trigger graft logic, and also
-    # keep track of which endpoint is dirty
-    dirtyc1 = not (base == _c1 or base.descendant(_c1))
-    dirtyc2 = not (base == _c2 or base.descendant(_c2))
-    graft = dirtyc1 or dirtyc2
-    tca = base
-    if graft:
-        tca = _c1.ancestor(_c2)
-
-    limit = copies._findlimit(repo, c1.rev(), c2.rev())
-    if limit is None:
-        # no common ancestor, no copies
-        return {}, {}, {}, {}, {}
-    repo.ui.debug("  searching for copies back to rev %d\n" % limit)
-
-    m1 = c1.manifest()
-    m2 = c2.manifest()
-    mb = base.manifest()
-
-    # gather data from _checkcopies:
-    # - diverge = record all diverges in this dict
-    # - copy = record all non-divergent copies in this dict
-    # - fullcopy = record all copies in this dict
-    # - incomplete = record non-divergent partial copies here
-    # - incompletediverge = record divergent partial copies here
-    diverge = {} # divergence data is shared
-    incompletediverge = {}
-    data1 = {'copy': {},
-             'fullcopy': {},
-             'incomplete': {},
-             'diverge': diverge,
-             'incompletediverge': incompletediverge,
-            }
-    data2 = {'copy': {},
-             'fullcopy': {},
-             'incomplete': {},
-             'diverge': diverge,
-             'incompletediverge': incompletediverge,
-            }
-
-    # find interesting file sets from manifests
-    addedinm1 = m1.filesnotin(mb)
-    addedinm2 = m2.filesnotin(mb)
-    bothnew = sorted(addedinm1 & addedinm2)
-    if tca == base:
-        # unmatched file from base
-        u1r, u2r = copies._computenonoverlap(repo, c1, c2, addedinm1, addedinm2)
-        u1u, u2u = u1r, u2r
-    else:
-        # unmatched file from base (DAG rotation in the graft case)
-        u1r, u2r = copies._computenonoverlap(repo, c1, c2, addedinm1, addedinm2,
-                                             baselabel='base')
-        # unmatched file from topological common ancestors (no DAG rotation)
-        # need to recompute this for directory move handling when grafting
-        mta = tca.manifest()
-        u1u, u2u = copies._computenonoverlap(repo, c1, c2, m1.filesnotin(mta),
-                                             m2.filesnotin(mta),
-                                             baselabel='topological common ancestor')
-
-    for f in u1u:
-        copies._checkcopies(c1, c2, f, base, tca, dirtyc1, limit, data1)
-
-    for f in u2u:
-        copies._checkcopies(c2, c1, f, base, tca, dirtyc2, limit, data2)
-
-    copy = dict(data1['copy'])
-    copy.update(data2['copy'])
-    fullcopy = dict(data1['fullcopy'])
-    fullcopy.update(data2['fullcopy'])
-
-    if dirtyc1:
-        copies._combinecopies(data2['incomplete'], data1['incomplete'], copy, diverge,
-                              incompletediverge)
-    else:
-        copies._combinecopies(data1['incomplete'], data2['incomplete'], copy, diverge,
-                              incompletediverge)
-
-    renamedelete = {}
-    renamedeleteset = set()
-    divergeset = set()
-    for of, fl in diverge.items():
-        if len(fl) == 1 or of in c1 or of in c2:
-            del diverge[of] # not actually divergent, or not a rename
-            if of not in c1 and of not in c2:
-                # renamed on one side, deleted on the other side, but filter
-                # out files that have been renamed and then deleted
-                renamedelete[of] = [f for f in fl if f in c1 or f in c2]
-                renamedeleteset.update(fl) # reverse map for below
-        else:
-            divergeset.update(fl) # reverse map for below
-
-    if bothnew:
-        repo.ui.debug("  unmatched files new in both:\n   %s\n"
-                      % "\n   ".join(bothnew))
-    bothdiverge = {}
-    bothincompletediverge = {}
-    remainder = {}
-    both1 = {'copy': {},
-             'fullcopy': {},
-             'incomplete': {},
-             'diverge': bothdiverge,
-             'incompletediverge': bothincompletediverge
-            }
-    both2 = {'copy': {},
-             'fullcopy': {},
-             'incomplete': {},
-             'diverge': bothdiverge,
-             'incompletediverge': bothincompletediverge
-            }
-    for f in bothnew:
-        copies._checkcopies(c1, c2, f, base, tca, dirtyc1, limit, both1)
-        copies._checkcopies(c2, c1, f, base, tca, dirtyc2, limit, both2)
-    if dirtyc1 and dirtyc2:
-        pass
-    elif dirtyc1:
-        # incomplete copies may only be found on the "dirty" side for bothnew
-        assert not both2['incomplete']
-        remainder = copies._combinecopies({}, both1['incomplete'], copy, bothdiverge,
-                                          bothincompletediverge)
-    elif dirtyc2:
-        assert not both1['incomplete']
-        remainder = copies._combinecopies({}, both2['incomplete'], copy, bothdiverge,
-                                          bothincompletediverge)
-    else:
-        # incomplete copies and divergences can't happen outside grafts
-        assert not both1['incomplete']
-        assert not both2['incomplete']
-        assert not bothincompletediverge
-    for f in remainder:
-        assert f not in bothdiverge
-        ic = remainder[f]
-        if ic[0] in (m1 if dirtyc1 else m2):
-            # backed-out rename on one side, but watch out for deleted files
-            bothdiverge[f] = ic
-    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
-
-    if fullcopy and repo.ui.debugflag:
-        repo.ui.debug("  all copies found (* = to merge, ! = divergent, "
-                      "% = renamed and deleted):\n")
-        for f in sorted(fullcopy):
-            note = ""
-            if f in copy:
-                note += "*"
-            if f in divergeset:
-                note += "!"
-            if f in renamedeleteset:
-                note += "%"
-            repo.ui.debug("   src: '%s' -> dst: '%s' %s\n" % (fullcopy[f], f,
-                                                              note))
-    del divergeset
-
-    if not fullcopy:
-        return copy, {}, diverge, renamedelete, {}
-
-    repo.ui.debug("  checking for directory renames\n")
-
-    # generate a directory move map
-    d1, d2 = c1.dirs(), c2.dirs()
-    # Hack for adding '', which is not otherwise added, to d1 and d2
-    d1.addpath('/')
-    d2.addpath('/')
-    invalid = set()
-    dirmove = {}
-
-    # examine each file copy for a potential directory move, which is
-    # when all the files in a directory are moved to a new directory
-    for dst, src in fullcopy.iteritems():
-        dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
-        if dsrc in invalid:
-            # already seen to be uninteresting
-            continue
-        elif dsrc in d1 and ddst in d1:
-            # directory wasn't entirely moved locally
-            invalid.add(dsrc + "/")
-        elif dsrc in d2 and ddst in d2:
-            # directory wasn't entirely moved remotely
-            invalid.add(dsrc + "/")
-        elif dsrc + "/" in dirmove and dirmove[dsrc + "/"] != ddst + "/":
-            # files from the same directory moved to two different places
-            invalid.add(dsrc + "/")
-        else:
-            # looks good so far
-            dirmove[dsrc + "/"] = ddst + "/"
-
-    for i in invalid:
-        if i in dirmove:
-            del dirmove[i]
-    del d1, d2, invalid
-
-    if not dirmove:
-        return copy, {}, diverge, renamedelete, {}
-
-    for d in dirmove:
-        repo.ui.debug("   discovered dir src: '%s' -> dst: '%s'\n" %
-                      (d, dirmove[d]))
-
-    movewithdir = {}
-    # check unaccounted nonoverlapping files against directory moves
-    for f in u1r + u2r:
-        if f not in fullcopy:
-            for d in dirmove:
-                if f.startswith(d):
-                    # new file added in a directory that was moved, move it
-                    df = dirmove[d] + f[len(d):]
-                    if df not in copy:
-                        movewithdir[f] = df
-                        repo.ui.debug(("   pending file src: '%s' -> "
-                                       "dst: '%s'\n") % (f, df))
-                    break
-
-    return copy, movewithdir, diverge, renamedelete, dirmove
-
 if util.safehasattr(copies, '_fullcopytracing'):
     copies._fullcopytracing = fixedcopytracing
-elif util.safehasattr(copies, 'mergecopies'):
-    # compat fix for hg <= 4.3
-    copies.mergecopies = fixoldmergecopies
 
 if not util.safehasattr(obsutil, "_succs"):
     class _succs(list):