fix bookmarks rollback behavior
Before this patch undo.bookmarks was created on bookmarks write and
not with other transaction-related files. There were two issues: first
is that if you have changed bookmarks few times after a transaction
happened, rollback will give you a state which can point to
non-existing revision. Second is that if you have not changed
bookmarks after a transaction, rollback will touch your state anyway.
This change also adds `localrepo._writejournal` method, which can be
used by other extensions to save their transaction-related backup in
right time.
--- a/mercurial/bookmarks.py Fri May 06 15:37:38 2011 +0300
+++ b/mercurial/bookmarks.py Sun May 01 13:07:00 2011 +0200
@@ -61,12 +61,6 @@
'''
refs = repo._bookmarks
- try:
- bms = repo.opener('bookmarks').read()
- except IOError:
- bms = ''
- repo.opener('undo.bookmarks', 'w').write(bms)
-
if repo._bookmarkcurrent not in refs:
setcurrent(repo, None)
for mark in refs.keys():
--- a/mercurial/localrepo.py Fri May 06 15:37:38 2011 +0300
+++ b/mercurial/localrepo.py Sun May 01 13:07:00 2011 +0200
@@ -669,6 +669,17 @@
raise error.RepoError(
_("abandoned transaction found - run hg recover"))
+ journalfiles = self._writejournal(desc)
+ renames = [(x, undoname(x)) for x in journalfiles]
+
+ tr = transaction.transaction(self.ui.warn, self.sopener,
+ self.sjoin("journal"),
+ aftertrans(renames),
+ self.store.createmode)
+ self._transref = weakref.ref(tr)
+ return tr
+
+ def _writejournal(self, desc):
# save dirstate for rollback
try:
ds = self.opener("dirstate").read()
@@ -679,16 +690,15 @@
encoding.fromlocal(self.dirstate.branch()))
self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc))
- renames = [(self.sjoin("journal"), self.sjoin("undo")),
- (self.join("journal.dirstate"), self.join("undo.dirstate")),
- (self.join("journal.branch"), self.join("undo.branch")),
- (self.join("journal.desc"), self.join("undo.desc"))]
- tr = transaction.transaction(self.ui.warn, self.sopener,
- self.sjoin("journal"),
- aftertrans(renames),
- self.store.createmode)
- self._transref = weakref.ref(tr)
- return tr
+ bkname = self.join('bookmarks')
+ if os.path.exists(bkname):
+ util.copyfile(bkname, self.join('journal.bookmarks'))
+ else:
+ self.opener('journal.bookmarks', 'w').write('')
+
+ return (self.sjoin('journal'), self.join('journal.dirstate'),
+ self.join('journal.branch'), self.join('journal.desc'),
+ self.join('journal.bookmarks'))
def recover(self):
lock = self.lock()
@@ -2027,6 +2037,11 @@
util.rename(src, dest)
return a
+def undoname(fn):
+ base, name = os.path.split(fn)
+ assert name.startswith('journal')
+ return os.path.join(base, name.replace('journal', 'undo', 1))
+
def instance(ui, path, create):
return localrepository(ui, util.drop_scheme('file', path), create)
--- a/tests/test-bookmarks.t Fri May 06 15:37:38 2011 +0300
+++ b/tests/test-bookmarks.t Sun May 01 13:07:00 2011 +0200
@@ -231,6 +231,7 @@
Y 2:db815d6d32e6
* Z 2:db815d6d32e6
x y 2:db815d6d32e6
+
test summary
$ hg summary
@@ -244,3 +245,16 @@
$ hg id
db815d6d32e6 tip Y/Z/x y
+
+test rollback
+
+ $ hg bookmark -f Y -r 1
+ $ hg bookmark -f Z -r 1
+ $ hg rollback
+ repository tip rolled back to revision 1 (undo commit)
+ working directory now based on revision 0
+ $ hg bookmarks
+ X 0:f7b1eb17ad24
+ X2 1:925d80f479bb
+ Y -1:000000000000
+ * Z 0:f7b1eb17ad24
--- a/tests/test-fncache.t Fri May 06 15:37:38 2011 +0300
+++ b/tests/test-fncache.t Sun May 01 13:07:00 2011 +0200
@@ -76,6 +76,7 @@
.hg/last-message.txt
.hg/requires
.hg/undo
+ .hg/undo.bookmarks
.hg/undo.branch
.hg/undo.desc
.hg/undo.dirstate
@@ -102,6 +103,7 @@
.hg/store/data/tst.d.hg
.hg/store/data/tst.d.hg/_foo.i
.hg/store/undo
+ .hg/undo.bookmarks
.hg/undo.branch
.hg/undo.desc
.hg/undo.dirstate
--- a/tests/test-hardlinks.t Fri May 06 15:37:38 2011 +0300
+++ b/tests/test-hardlinks.t Sun May 01 13:07:00 2011 +0200
@@ -195,6 +195,7 @@
2 r4/.hg/store/data/f1.i
2 r4/.hg/store/fncache
2 r4/.hg/store/undo
+ 2 r4/.hg/undo.bookmarks
2 r4/.hg/undo.branch
2 r4/.hg/undo.desc
2 r4/.hg/undo.dirstate
@@ -223,6 +224,7 @@
2 r4/.hg/store/data/f1.i
2 r4/.hg/store/fncache
2 r4/.hg/store/undo
+ 2 r4/.hg/undo.bookmarks
2 r4/.hg/undo.branch
2 r4/.hg/undo.desc
2 r4/.hg/undo.dirstate
--- a/tests/test-hup.t Fri May 06 15:37:38 2011 +0300
+++ b/tests/test-hup.t Sun May 01 13:07:00 2011 +0200
@@ -17,4 +17,4 @@
rollback completed
killed!
$ echo .hg/* .hg/store/*
- .hg/00changelog.i .hg/journal.branch .hg/journal.desc .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a
+ .hg/00changelog.i .hg/journal.bookmarks .hg/journal.branch .hg/journal.desc .hg/journal.dirstate .hg/requires .hg/store .hg/store/00changelog.i .hg/store/00changelog.i.a
--- a/tests/test-inherit-mode.t Fri May 06 15:37:38 2011 +0300
+++ b/tests/test-inherit-mode.t Sun May 01 13:07:00 2011 +0200
@@ -77,6 +77,7 @@
00660 ./.hg/store/data/foo.i
00660 ./.hg/store/fncache
00660 ./.hg/store/undo
+ 00660 ./.hg/undo.bookmarks
00660 ./.hg/undo.branch
00660 ./.hg/undo.desc
00660 ./.hg/undo.dirstate
@@ -117,6 +118,7 @@
00660 ../push/.hg/store/data/foo.i
00660 ../push/.hg/store/fncache
00660 ../push/.hg/store/undo
+ 00660 ../push/.hg/undo.bookmarks
00660 ../push/.hg/undo.branch
00660 ../push/.hg/undo.desc
00660 ../push/.hg/undo.dirstate