mercurial/copies.py
changeset 43299 83bb1e89ab9b
parent 43297 8a2925265402
child 43300 ffd04bc9f57d
equal deleted inserted replaced
43298:dda9482f60d2 43299:83bb1e89ab9b
     6 # GNU General Public License version 2 or any later version.
     6 # GNU General Public License version 2 or any later version.
     7 
     7 
     8 from __future__ import absolute_import
     8 from __future__ import absolute_import
     9 
     9 
    10 import collections
    10 import collections
    11 import heapq
       
    12 import os
    11 import os
    13 
    12 
    14 from .i18n import _
    13 from .i18n import _
    15 
    14 
    16 
    15 
   227     children = {}
   226     children = {}
   228     revinfo = _revinfogetter(repo)
   227     revinfo = _revinfogetter(repo)
   229 
   228 
   230     cl = repo.changelog
   229     cl = repo.changelog
   231     missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
   230     missingrevs = cl.findmissingrevs(common=[a.rev()], heads=[b.rev()])
       
   231     mrset = set(missingrevs)
       
   232     roots = set()
   232     for r in missingrevs:
   233     for r in missingrevs:
   233         for p in cl.parentrevs(r):
   234         for p in cl.parentrevs(r):
   234             if p == node.nullrev:
   235             if p == node.nullrev:
   235                 continue
   236                 continue
   236             if p not in children:
   237             if p not in children:
   237                 children[p] = [r]
   238                 children[p] = [r]
   238             else:
   239             else:
   239                 children[p].append(r)
   240                 children[p].append(r)
   240 
   241             if p not in mrset:
   241     roots = set(children) - set(missingrevs)
   242                 roots.add(p)
   242     work = list(roots)
   243     if not roots:
       
   244         # no common revision to track copies from
       
   245         return {}
       
   246     min_root = min(roots)
       
   247 
       
   248     from_head = set(
       
   249         cl.reachableroots(min_root, [b.rev()], list(roots), includepath=True)
       
   250     )
       
   251 
       
   252     iterrevs = set(from_head)
       
   253     iterrevs &= mrset
       
   254     iterrevs.update(roots)
       
   255     iterrevs.remove(b.rev())
   243     all_copies = {r: {} for r in roots}
   256     all_copies = {r: {} for r in roots}
   244     heapq.heapify(work)
       
   245     alwaysmatch = match.always()
   257     alwaysmatch = match.always()
   246     while work:
   258     for r in sorted(iterrevs):
   247         r = heapq.heappop(work)
       
   248         copies = all_copies.pop(r)
   259         copies = all_copies.pop(r)
   249         if r == b.rev():
       
   250             return copies
       
   251         for i, c in enumerate(children[r]):
   260         for i, c in enumerate(children[r]):
   252             p1, p2, p1copies, p2copies, removed = revinfo(c)
   261             p1, p2, p1copies, p2copies, removed = revinfo(c)
   253             if r == p1:
   262             if r == p1:
   254                 parent = 1
   263                 parent = 1
   255                 childcopies = p1copies
   264                 childcopies = p1copies
   271             for f in removed:
   280             for f in removed:
   272                 if f in newcopies:
   281                 if f in newcopies:
   273                     del newcopies[f]
   282                     del newcopies[f]
   274             othercopies = all_copies.get(c)
   283             othercopies = all_copies.get(c)
   275             if othercopies is None:
   284             if othercopies is None:
   276                 heapq.heappush(work, c)
       
   277                 all_copies[c] = newcopies
   285                 all_copies[c] = newcopies
   278             else:
   286             else:
   279                 # we are the second parent to work on c, we need to merge our
   287                 # we are the second parent to work on c, we need to merge our
   280                 # work with the other.
   288                 # work with the other.
   281                 #
   289                 #
   291                 if parent == 1:
   299                 if parent == 1:
   292                     othercopies.update(newcopies)
   300                     othercopies.update(newcopies)
   293                 else:
   301                 else:
   294                     newcopies.update(othercopies)
   302                     newcopies.update(othercopies)
   295                     all_copies[c] = newcopies
   303                     all_copies[c] = newcopies
   296     assert False
   304     return all_copies[b.rev()]
   297 
   305 
   298 
   306 
   299 def _forwardcopies(a, b, base=None, match=None):
   307 def _forwardcopies(a, b, base=None, match=None):
   300     """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
   308     """find {dst@b: src@a} copy mapping where a is an ancestor of b"""
   301 
   309