[PATCH 2 of 2 STABLE] revlog: fix lazyparser.__iter__() to see all revisions

Greg Ward greg-hg at gerg.ca
Wed Apr 14 09:10:22 CDT 2010


# HG changeset patch
# User Greg Ward <greg-hg at gerg.ca>
# Date 1271254132 14400
# Branch stable
# Node ID 02e76c11eee97d454e8dcfca4752d73572b0b92b
# Parent  fcd774f7d93d55fc74c04a4f8cb9c7ef7722af1c
revlog: fix lazyparser.__iter__() to see all revisions.
(issue2137)

Previously, it only returned revisions that were in the revlog when it
was originally opened; revisions added since then were invisible.
This broke revlog._partialmatch() and therefore repo.lookup().

diff --git a/mercurial/revlog.py b/mercurial/revlog.py
--- a/mercurial/revlog.py
+++ b/mercurial/revlog.py
@@ -294,8 +294,7 @@
         return key in self.p.map
     def __iter__(self):
         yield nullid
-        for i in xrange(self.p.l):
-            ret = self.p.index[i]
+        for i, ret in enumerate(self.p.index):
             if not ret:
                 self.p.loadindex(i)
                 ret = self.p.index[i]
diff --git a/tests/issue2137.py b/tests/issue2137.py
new file mode 100755
--- /dev/null
+++ b/tests/issue2137.py
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+
+# reproduce issue 2137 (revlog's lazyparser not properly updated after
+# adding changesets, causing repo.lookup() to fail spuriously)
+
+import sys
+from mercurial import ui as hgui, hg, commands, node as hgnode, error, revlog
+
+(path) = sys.argv[1]
+
+revlog._prereadsize = 128               # force use of lazyparser
+ui = hgui.ui()
+ui.write('opening %s\n' % path)
+repo = hg.repository(ui, path)
+
+ui.write('initial sanity check\n')
+assert len(repo) == len(repo.changelog.index) - 1 == repo.changelog.nodemap.p.l
+tip = repo.changelog.tip()
+assert repo.lookup(hgnode.short(tip)) == tip
+
+ui.write('committing\n')
+open(repo.wjoin('b'), 'a').write('boo\n')
+repo.commit(text='modify b',
+            user='test',
+            date=(3, 0))
+
+# demonstrate the bug: looking up the abbreviated changeset ID of a
+# changeset that is known to be in the changelog fails
+ui.write('test: repo.lookup()\n')
+tip1 = repo.changelog.tip()
+try:
+    tip2 = repo.lookup(hgnode.short(tip1))
+    assert tip1 == tip2
+    print "PASS: looked up tip two ways and got consistent results"
+except error.RepoLookupError:
+    print "FAIL: failed to lookup abbreviated changeset ID of tip"
diff --git a/tests/test-issue2137 b/tests/test-issue2137
new file mode 100755
--- /dev/null
+++ b/tests/test-issue2137
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+echo "% setup"
+hg init repo1
+
+# need to do this in Python in order to monkeypatch revlog._maxinline
+cat > prep.py <<EOF
+import os
+from mercurial import ui, hg, revlog
+
+revlog._maxinline = 128
+os.chdir('repo1')
+ui = ui.ui()
+repo = hg.repository(ui, '.')
+
+open('a', 'a').write('a\n')
+repo.add(['a'])
+repo.commit(text='add a with a long commit message to make the changelog a bit bigger',
+            user='test test test test test test test test test test test',
+            date=(0, 0))
+
+open('b', 'a').write('b\n')
+repo.add(['b'])
+repo.commit(text='add b and ramble on a bit here too for the same reason',
+            user='test test test test test test test test test test test',
+            date=(1, 0))
+EOF
+#echo $PYTHON prep.py
+$PYTHON prep.py
+#hg -R repo1 log -v
+
+# changelog must be split into *.d and *.i, and *.i must be > 128 bytes
+ls -1 repo1/.hg/store/00changelog.*
+
+echo ""
+echo "% demonstrate the bug"
+#echo $PYTHON $TESTDIR/issue2137.py .
+$PYTHON $TESTDIR/issue2137.py repo1


More information about the Mercurial-devel mailing list