changeset 19504:2fa303619b4d stable

ancestor.deepest: ignore ninteresting while building result (issue3984) ninteresting indicates the number of non-zero elements in the interesting array, not the number of elements in the final list. Since elements in interesting can stand for more than one gca, limiting the number of results to ninteresting is an error. Tests for issue3984 are included.
author Siddharth Agarwal <sid0@fb.com>
date Thu, 25 Jul 2013 14:43:15 -0700
parents f2dfda6ac152
children 7b815e38022a
files mercurial/parsers.c tests/test-ancestor.py
diffstat 2 files changed, 32 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/parsers.c	Thu Jul 25 17:35:53 2013 +0800
+++ b/mercurial/parsers.c	Thu Jul 25 14:43:15 2013 -0700
@@ -1388,8 +1388,7 @@
 	if (dict == NULL)
 		goto bail;
 
-	j = ninteresting;
-	for (i = 0; i < revcount && j > 0; i++) {
+	for (i = 0; i < revcount; i++) {
 		PyObject *key;
 
 		if ((final & (1 << i)) == 0)
@@ -1403,7 +1402,6 @@
 			Py_DECREF(Py_None);
 			goto bail;
 		}
-		j -= 1;
 	}
 
 	keys = PyDict_Keys(dict);
--- a/tests/test-ancestor.py	Thu Jul 25 17:35:53 2013 +0800
+++ b/tests/test-ancestor.py	Thu Jul 25 14:43:15 2013 -0700
@@ -1,4 +1,4 @@
-from mercurial import ancestor
+from mercurial import ancestor, commands, hg, ui, util
 
 # graph is a dict of child->parent adjacency lists for this graph:
 # o  13
@@ -101,6 +101,36 @@
     s = genlazyancestors([11, 13], stoprev=6, inclusive=True)
     printlazyancestors(s, [11, 13, 7, 9, 8, 3, 6, 4, 1, -1, 0])
 
+
+# The C gca algorithm requires a real repo. These are textual descriptions of
+# dags that have been known to be problematic.
+dagtests = [
+    '+2*2*2/*3/2',
+    '+3*3/*2*2/*4*4/*4/2*4/2*2',
+]
+def test_gca():
+    u = ui.ui()
+    for i, dag in enumerate(dagtests):
+        repo = hg.repository(u, 'gca%d' % i, create=1)
+        cl = repo.changelog
+        if not util.safehasattr(cl.index, 'ancestors'):
+            # C version not available
+            return
+
+        commands.debugbuilddag(u, repo, dag)
+        # Compare the results of the Python and C versions. This does not
+        # include choosing a winner when more than one gca exists -- we make
+        # sure both return exactly the same set of gcas.
+        for a in cl:
+            for b in cl:
+                cgcas = sorted(cl.index.ancestors(a, b))
+                pygcas = sorted(ancestor.ancestors(cl.parentrevs, a, b))
+                if cgcas != pygcas:
+                    print "test_gca: for dag %s, gcas for %d, %d:" % (dag, a, b)
+                    print "  C returned:      %s" % cgcas
+                    print "  Python returned: %s" % pygcas
+
 if __name__ == '__main__':
     test_missingancestors()
     test_lazyancestors()
+    test_gca()