changeset 12392:741290486877 stable

bookmarks: fix _bookmarks/lookup() reentrancy issue (issue2016) _bookmarks is loaded lazily and calls super.lookup(). Unfortunately, branch and tags caches initializations also recurse in lookup() and end up trying to access _bookmarks again. Massive confusion ensues. I considered fixing all branches and tags cache loading to avoid recursing in lookup() but it would add complexity to otherwise working code provided lookups are performed on nodes or revnums.
author Patrick Mezard <pmezard@gmail.com>
date Fri, 24 Sep 2010 00:03:58 +0200
parents ca5fd84d62c6
children 84ceedcfeb6a
files hgext/bookmarks.py tests/test-bookmarks-strip tests/test-bookmarks-strip.out
diffstat 3 files changed, 28 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/bookmarks.py	Thu Sep 23 11:41:27 2010 +0200
+++ b/hgext/bookmarks.py	Fri Sep 24 00:03:58 2010 +0200
@@ -224,6 +224,7 @@
             in the .hg/bookmarks file.
             Read the file and return a (name=>nodeid) dictionary
             '''
+            self._loadingbookmarks = True
             try:
                 bookmarks = {}
                 for line in self.opener('bookmarks'):
@@ -231,6 +232,7 @@
                     bookmarks[refspec] = super(bookmark_repo, self).lookup(sha)
             except:
                 pass
+            self._loadingbookmarks = False
             return bookmarks
 
         @util.propertycache
@@ -257,8 +259,9 @@
             return super(bookmark_repo, self).rollback(*args)
 
         def lookup(self, key):
-            if key in self._bookmarks:
-                key = self._bookmarks[key]
+            if not getattr(self, '_loadingbookmarks', False):
+                if key in self._bookmarks:
+                    key = self._bookmarks[key]
             return super(bookmark_repo, self).lookup(key)
 
         def _bookmarksupdate(self, parents, node):
@@ -357,7 +360,8 @@
         def _findtags(self):
             """Merge bookmarks with normal tags"""
             (tags, tagtypes) = super(bookmark_repo, self)._findtags()
-            tags.update(self._bookmarks)
+            if not getattr(self, '_loadingbookmarks', False):
+                tags.update(self._bookmarks)
             return (tags, tagtypes)
 
         if hasattr(repo, 'invalidate'):
--- a/tests/test-bookmarks-strip	Thu Sep 23 11:41:27 2010 +0200
+++ b/tests/test-bookmarks-strip	Fri Sep 24 00:03:58 2010 +0200
@@ -43,3 +43,18 @@
 echo % list bookmarks
 hg book
 
+echo '% test immediate rollback and reentrancy issue'
+echo "mq=!" >> $HGRCPATH
+hg init repo
+cd repo
+echo a > a
+hg ci -Am adda
+echo b > b
+hg ci -Am addb
+hg bookmarks markb
+hg rollback
+hg bookmarks
+hg bookmarks markb
+hg bookmarks
+cd ..
+
--- a/tests/test-bookmarks-strip.out	Thu Sep 23 11:41:27 2010 +0200
+++ b/tests/test-bookmarks-strip.out	Fri Sep 24 00:03:58 2010 +0200
@@ -16,3 +16,9 @@
 % list bookmarks
  * test                      1:9f1b7e78eff8
  * test2                     1:9f1b7e78eff8
+% test immediate rollback and reentrancy issue
+adding a
+adding b
+rolling back to revision 0 (undo commit)
+no bookmarks set
+ * markb                     0:07f494440405