# HG changeset patch # User Pierre-Yves David # Date 1309528819 -7200 # Node ID 423c62a146c733524cabbcd6d1528e287e557ccc # Parent 93dd72d028a152e2d501ce097747cdc2d4bf7e3b add rollback support. diff -r 93dd72d028a1 -r 423c62a146c7 states.py --- a/states.py Fri Jul 01 14:55:02 2011 +0200 +++ b/states.py Fri Jul 01 16:00:19 2011 +0200 @@ -17,7 +17,9 @@ name are not fixed yet. ''' +import os from functools import partial + from mercurial.i18n import _ from mercurial import cmdutil from mercurial import scmutil @@ -31,6 +33,7 @@ from mercurial import extensions from mercurial import wireproto from mercurial import pushkey +from mercurial.lock import release _NOSHARE=2 @@ -196,6 +199,8 @@ opull = repo.pull opush = repo.push o_tag = repo._tag + orollback = repo.rollback + o_writejournal = repo._writejournal class statefulrepo(repo.__class__): def nodestate(self, node): @@ -236,11 +241,13 @@ except IOError: pass return heads - def _readstatesheads(self): + + def _readstatesheads(self, undo=False): statesheads = {} for state in STATES: if state.trackheads: - filename = 'states/%s-heads' % state.name + filemask = 'states/%s-heads' + filename = filemask % state.name statesheads[state] = self._readheadsfile(filename) return statesheads @@ -333,10 +340,47 @@ remote = map(node.bin, remote.listkeys('immutableheads')) return remote + ### Tag support + def _tag(self, names, node, *args, **kwargs): tagnode = o_tag(names, node, *args, **kwargs) self.setstate(ST0, [node, tagnode]) return tagnode + ### rollback support + + def _writejournal(self, desc): + entries = list(o_writejournal(desc)) + for state in STATES: + if state.trackheads: + filename = 'states/%s-heads' % state.name + filepath = self.join(filename) + if os.path.exists(filepath): + journalname = 'states/journal.%s-heads' % state.name + journalpath = self.join(journalname) + util.copyfile(filepath, journalpath) + entries.append(journalpath) + return tuple(entries) + + def rollback(self, dryrun=False): + wlock = lock = None + try: + wlock = self.wlock() + lock = self.lock() + ret = orollback(dryrun) + if not (ret or dryrun): #rollback did not failed + for state in STATES: + if state.trackheads: + src = self.join('states/undo.%s-heads') % state.name + dest = self.join('states/%s-heads') % state.name + if os.path.exists(src): + util.rename(src, dest) + elif os.path.exists(dest): #unlink in any case + os.unlink(dest) + self.__dict__.pop('_statesheads', None) + return ret + finally: + release(lock, wlock) + repo.__class__ = statefulrepo diff -r 93dd72d028a1 -r 423c62a146c7 tests/test-ready.t --- a/tests/test-ready.t Fri Jul 01 14:55:02 2011 +0200 +++ b/tests/test-ready.t Fri Jul 01 16:00:19 2011 +0200 @@ -143,4 +143,50 @@ date: Thu Jan 01 00:00:00 1970 +0000 summary: Added tag babar for changeset cdaaa31e4239 +Check rollback + $ hg merge + 1 files updated, 0 files merged, 0 files removed, 0 files unresolved + (branch merge, don't forget to commit) + $ hg commit -m 'merge' + $ hg published tip + $ hg log -r 'publishedheads()' + changeset: 7:26631d82e09e + tag: tip + parent: 6:bd66bf1525ee + parent: 5:cdaaa31e4239 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge + +test rollback does not mess up the liquid changeset + $ mkcommit bibi + $ hg rollback + repository tip rolled back to revision 7 (undo commit) + working directory now based on revision 7 + $ hg log -r 'publishedheads()' + changeset: 7:26631d82e09e + tag: tip + parent: 6:bd66bf1525ee + parent: 5:cdaaa31e4239 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge + + +test rollback even when rollbacking frozen + + $ mkcommit bubu + $ hg published tip + $ hg rollback + repository tip rolled back to revision 7 (undo commit) + working directory now based on revision 7 + $ hg log -r 'publishedheads()' + changeset: 7:26631d82e09e + tag: tip + parent: 6:bd66bf1525ee + parent: 5:cdaaa31e4239 + user: test + date: Thu Jan 01 00:00:00 1970 +0000 + summary: merge +