[PATCH 3 of 5] revlog: choose a consistent ancestor when there's a tie
Bryan O'Sullivan
bos at serpentine.com
Wed May 2 18:22:40 CDT 2012
# HG changeset patch
# User Bryan O'Sullivan <bryano at fb.com>
# Date 1336000783 25200
# Branch stable
# Node ID 52d62ae25ab408f3c645790feb78f564383588bd
# Parent 085f1ae5c96b522c6cd15acfa4c7c45f8dcda545
revlog: choose a consistent ancestor when there's a tie
Previously, we chose a rev based on numeric ordering, which could
cause "the same merge" in topologically identical but numerically
different repos to choose different merge bases.
diff -r 085f1ae5c96b -r 52d62ae25ab4 mercurial/ancestor.py
--- a/mercurial/ancestor.py Wed May 02 16:19:42 2012 -0700
+++ b/mercurial/ancestor.py Wed May 02 16:19:43 2012 -0700
@@ -235,25 +235,3 @@
depth[vertex] = 0
visit.pop()
return depth
-
-def ancestor(a, b, pfunc):
- xs = ancestors(pfunc, a, b)
- y = genericancestor(a, b, pfunc)
- if y == -1:
- y = None
- if not xs:
- if y is None:
- return None
- print xs, y
- raise error.RepoError('ancestors disagree on whether a gca exists')
- elif y is None:
- print xs, y
- raise error.RepoError('ancestors disagree on whether a gca exists')
- if y in xs:
- return y
- xds = finddepths(xs, pfunc)
- xds = [ds[x] for x in xs]
- yd = finddepths([y], pfunc)[y]
- if len([xd != yd for xd in xds]) > 0:
- raise error.RepoError('ancestor depths do not match')
- return xs.pop()
diff -r 085f1ae5c96b -r 52d62ae25ab4 mercurial/revlog.py
--- a/mercurial/revlog.py Wed May 02 16:19:42 2012 -0700
+++ b/mercurial/revlog.py Wed May 02 16:19:43 2012 -0700
@@ -706,17 +706,14 @@
def ancestor(self, a, b):
"""calculate the least common ancestor of nodes a and b"""
- # fast path, check if it is a descendant
a, b = self.rev(a), self.rev(b)
- start, end = sorted((a, b))
- if self.descendant(start, end):
- return self.node(start)
-
- c = ancestor.ancestor(a, b, self.parentrevs)
- if c is None:
+ ancs = ancestor.ancestors(self.parentrevs, a, b)
+ if not ancs:
return nullid
-
- return self.node(c)
+ if len(ancs) == 1:
+ return self.node(ancs.pop())
+ # choose a consistent winner when there's a tie
+ return sorted(map(self.node, ancs))[0]
def _match(self, id):
if isinstance(id, (long, int)):
More information about the Mercurial-devel
mailing list