copies: consider nullrev a common ancestor
authorMartin von Zweigbergk <martinvonz@google.com>
Tue, 15 Jan 2019 11:16:42 -0800
changeset 41414 b80af0707066
parent 41413 bc843e251134
child 41415 dc50121126ae
copies: consider nullrev a common ancestor I've seen many bugs in the git codebase that were caused by it not having a null revision and being forced to treat root commits differently. Mercurial has a null revision and I think it's generally a bug to treat it differently from other commits in graph algorithms. This effectively undoes 83cfa1baf8ad (copies: don't report copies with unrelated branch, 2010-01-01). The test cases that that commit added still passes. I suspect some other fix after that commit made it unnecessary. Differential Revision: https://phab.mercurial-scm.org/D5594
mercurial/copies.py
--- a/mercurial/copies.py	Thu Jan 17 09:18:48 2019 -0800
+++ b/mercurial/copies.py	Tue Jan 15 11:16:42 2019 -0800
@@ -31,7 +31,6 @@
     Generally, this means finding the earliest revision number that's an
     ancestor of a or b but not both, except when a or b is a direct descendent
     of the other, in which case we can return the minimum revnum of a and b.
-    None if no such revision exists.
     """
 
     # basic idea:
@@ -55,7 +54,6 @@
     visit = [-a, -b]
     heapq.heapify(visit)
     interesting = len(visit)
-    hascommonancestor = False
     limit = node.wdirrev
 
     while interesting:
@@ -64,9 +62,9 @@
             parents = [cl.rev(p) for p in repo.dirstate.parents()]
         else:
             parents = cl.parentrevs(r)
+        if parents[1] == node.nullrev:
+            parents = parents[:1]
         for p in parents:
-            if p < 0:
-                continue
             if p not in side:
                 # first time we see p; add it to visit
                 side[p] = side[r]
@@ -77,14 +75,10 @@
                 # p was interesting but now we know better
                 side[p] = 0
                 interesting -= 1
-                hascommonancestor = True
         if side[r]:
             limit = r # lowest rev visited
             interesting -= 1
 
-    if not hascommonancestor:
-        return None
-
     # Consider the following flow (see test-commit-amend.t under issue4405):
     # 1/ File 'a0' committed
     # 2/ File renamed from 'a0' to 'a1' in a new commit (call it 'a1')
@@ -169,8 +163,6 @@
         dbg('debug.copies:    looking into rename from %s to %s\n'
             % (a, b))
     limit = _findlimit(repo, a.rev(), b.rev())
-    if limit is None:
-        limit = node.nullrev
     if debug:
         dbg('debug.copies:      search limit: %d\n' % limit)
     am = a.manifest()
@@ -465,9 +457,6 @@
         tca = _c1.ancestor(_c2)
 
     limit = _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()