bookmarks: fix _bookmarks/lookup() reentrancy issue (issue2016) stable
authorPatrick Mezard <pmezard@gmail.com>
Fri, 24 Sep 2010 00:03:58 +0200
branchstable
changeset 12392 741290486877
parent 12391 ca5fd84d62c6
child 12393 84ceedcfeb6a
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.
hgext/bookmarks.py
tests/test-bookmarks-strip
tests/test-bookmarks-strip.out
--- 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