Mercurial > hg
comparison mercurial/localrepo.py @ 14266:89e7d35e0ef0 stable
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.
author | Alexander Solovyov <alexander@solovyov.net> |
---|---|
date | Sun, 01 May 2011 13:07:00 +0200 |
parents | 044e1356327d |
children | a55a0045704c 4d958d1bb072 |
comparison
equal
deleted
inserted
replaced
14211:b00ab6890fe9 | 14266:89e7d35e0ef0 |
---|---|
667 # abort here if the journal already exists | 667 # abort here if the journal already exists |
668 if os.path.exists(self.sjoin("journal")): | 668 if os.path.exists(self.sjoin("journal")): |
669 raise error.RepoError( | 669 raise error.RepoError( |
670 _("abandoned transaction found - run hg recover")) | 670 _("abandoned transaction found - run hg recover")) |
671 | 671 |
672 journalfiles = self._writejournal(desc) | |
673 renames = [(x, undoname(x)) for x in journalfiles] | |
674 | |
675 tr = transaction.transaction(self.ui.warn, self.sopener, | |
676 self.sjoin("journal"), | |
677 aftertrans(renames), | |
678 self.store.createmode) | |
679 self._transref = weakref.ref(tr) | |
680 return tr | |
681 | |
682 def _writejournal(self, desc): | |
672 # save dirstate for rollback | 683 # save dirstate for rollback |
673 try: | 684 try: |
674 ds = self.opener("dirstate").read() | 685 ds = self.opener("dirstate").read() |
675 except IOError: | 686 except IOError: |
676 ds = "" | 687 ds = "" |
677 self.opener("journal.dirstate", "w").write(ds) | 688 self.opener("journal.dirstate", "w").write(ds) |
678 self.opener("journal.branch", "w").write( | 689 self.opener("journal.branch", "w").write( |
679 encoding.fromlocal(self.dirstate.branch())) | 690 encoding.fromlocal(self.dirstate.branch())) |
680 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc)) | 691 self.opener("journal.desc", "w").write("%d\n%s\n" % (len(self), desc)) |
681 | 692 |
682 renames = [(self.sjoin("journal"), self.sjoin("undo")), | 693 bkname = self.join('bookmarks') |
683 (self.join("journal.dirstate"), self.join("undo.dirstate")), | 694 if os.path.exists(bkname): |
684 (self.join("journal.branch"), self.join("undo.branch")), | 695 util.copyfile(bkname, self.join('journal.bookmarks')) |
685 (self.join("journal.desc"), self.join("undo.desc"))] | 696 else: |
686 tr = transaction.transaction(self.ui.warn, self.sopener, | 697 self.opener('journal.bookmarks', 'w').write('') |
687 self.sjoin("journal"), | 698 |
688 aftertrans(renames), | 699 return (self.sjoin('journal'), self.join('journal.dirstate'), |
689 self.store.createmode) | 700 self.join('journal.branch'), self.join('journal.desc'), |
690 self._transref = weakref.ref(tr) | 701 self.join('journal.bookmarks')) |
691 return tr | |
692 | 702 |
693 def recover(self): | 703 def recover(self): |
694 lock = self.lock() | 704 lock = self.lock() |
695 try: | 705 try: |
696 if os.path.exists(self.sjoin("journal")): | 706 if os.path.exists(self.sjoin("journal")): |
2025 def a(): | 2035 def a(): |
2026 for src, dest in renamefiles: | 2036 for src, dest in renamefiles: |
2027 util.rename(src, dest) | 2037 util.rename(src, dest) |
2028 return a | 2038 return a |
2029 | 2039 |
2040 def undoname(fn): | |
2041 base, name = os.path.split(fn) | |
2042 assert name.startswith('journal') | |
2043 return os.path.join(base, name.replace('journal', 'undo', 1)) | |
2044 | |
2030 def instance(ui, path, create): | 2045 def instance(ui, path, create): |
2031 return localrepository(ui, util.drop_scheme('file', path), create) | 2046 return localrepository(ui, util.drop_scheme('file', path), create) |
2032 | 2047 |
2033 def islocal(path): | 2048 def islocal(path): |
2034 return True | 2049 return True |