Rollback support
authorPierre-Yves David <pierre-yves.david@logilab.fr>
Thu, 08 Sep 2011 17:32:51 +0200
changeset 52 62bdc2567099
parent 51 d98e06ab8320
child 53 0bcbf690dfca
Rollback support
hgext/obsolete.py
tests/test-obsolete.t
--- a/hgext/obsolete.py	Thu Sep 08 17:15:20 2011 +0200
+++ b/hgext/obsolete.py	Thu Sep 08 17:32:51 2011 +0200
@@ -5,6 +5,7 @@
 #
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
+import os
 
 from mercurial import util
 from mercurial import context
@@ -15,6 +16,7 @@
 from mercurial import discovery
 from mercurial import error
 from mercurial.node import hex, bin
+from mercurial.lock import release
 
 # Patch changectx
 #############################
@@ -119,6 +121,8 @@
 
     opull = repo.pull
     opush = repo.push
+    orollback = repo.rollback
+    o_writejournal = repo._writejournal
 
     class obsoletingrepo(repo.__class__):
 
@@ -222,6 +226,39 @@
                 pass #unknow revision (but keep propagating the data
             self._writeobsrels()
 
+        ### rollback support
+
+        def _writejournal(self, desc):
+            entries = list(o_writejournal(desc))
+            filename = 'obsolete-relations'
+            filepath = self.join(filename)
+            if  os.path.exists(filepath):
+                journalname = 'journal.' + filename
+                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
+                    src = self.join('undo.obsolete-relations')
+                    dst = self.join('obsolete-relations')
+                    if os.path.exists(src):
+                        util.rename(src, dst)
+                    elif os.path.exists(dst): #unlink in any case
+                        os.unlink(dst)
+                    # invalidate cache
+                    self.__dict__.pop('_obssubrels', None)
+                    self.__dict__.pop('_obsobjrels', None)
+                return ret
+            finally:
+                release(lock, wlock)
+
     repo.__class__ = obsoletingrepo
 
 
--- a/tests/test-obsolete.t	Thu Sep 08 17:15:20 2011 +0200
+++ b/tests/test-obsolete.t	Thu Sep 08 17:32:51 2011 +0200
@@ -203,3 +203,44 @@
   0
   - 1f0dee641bb7
 
+Test rollback support
+
+  $ hg up .^ -q
+  $ mkcommit "obsol_d''"
+  created new head
+  $ hg debugobsolete 8 7
+  $ hg -R ../other-new pull .
+  pulling from .
+  searching for changes
+  adding changesets
+  adding manifests
+  adding file changes
+  added 1 changesets with 1 changes to 1 files (+1 heads)
+  (run 'hg heads .' to see heads, 'hg merge' to merge)
+
+  $ qlog -R ../other-new
+  8
+  - 159dfc9fa5d3
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+  $ hg -R ../other-new rollback
+  repository tip rolled back to revision 7 (undo pull)
+  working directory now based on revision -1
+  $ qlog -R ../other-new
+  7
+  - 909a0fb57e5d
+  3
+  - 725c380fe99b
+  2
+  - 0d3f46688ccc
+  1
+  - 7c3bad9141dc
+  0
+  - 1f0dee641bb7
+