changeset 23311:64ab33ffba14

transaction: use the location value when doing backup We finally use the 'location' value coupled with the 'vfsmap' to restore backup for the right file.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Fri, 17 Oct 2014 21:04:35 -0700
parents 5bd1f6572db0
children 006e9ef05c31
files mercurial/localrepo.py mercurial/transaction.py
diffstat 2 files changed, 26 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/localrepo.py	Fri Oct 17 20:49:39 2014 -0700
+++ b/mercurial/localrepo.py	Fri Oct 17 21:04:35 2014 -0700
@@ -919,7 +919,9 @@
         try:
             if self.svfs.exists("journal"):
                 self.ui.status(_("rolling back interrupted transaction\n"))
-                transaction.rollback(self.sopener, "journal",
+                vfsmap = {'': self.sopener,
+                          'plain': self.opener,}
+                transaction.rollback(self.sopener, vfsmap, "journal",
                                      self.ui.warn)
                 self.invalidate()
                 return True
@@ -975,7 +977,8 @@
 
         parents = self.dirstate.parents()
         self.destroying()
-        transaction.rollback(self.sopener, 'undo', ui.warn)
+        vfsmap = {'plain': self.opener}
+        transaction.rollback(self.sopener, vfsmap, 'undo', ui.warn)
         if self.vfs.exists('undo.bookmarks'):
             self.vfs.rename('undo.bookmarks', 'bookmarks')
         if self.svfs.exists('undo.phaseroots'):
--- a/mercurial/transaction.py	Fri Oct 17 20:49:39 2014 -0700
+++ b/mercurial/transaction.py	Fri Oct 17 21:04:35 2014 -0700
@@ -25,7 +25,8 @@
         return func(self, *args, **kwds)
     return _active
 
-def _playback(journal, report, opener, entries, backupentries, unlink=True):
+def _playback(journal, report, opener, vfsmap, entries, backupentries,
+              unlink=True):
     for f, o, _ignore in entries:
         if o or not unlink:
             try:
@@ -44,9 +45,10 @@
 
     backupfiles = []
     for l, f, b, c in backupentries:
+        vfs = vfsmap[l]
         if f and b:
-            filepath = opener.join(f)
-            backuppath = opener.join(b)
+            filepath = vfs.join(f)
+            backuppath = vfs.join(b)
             try:
                 util.copyfile(backuppath, filepath)
                 backupfiles.append(b)
@@ -56,7 +58,7 @@
         else:
             target = f or b
             try:
-                opener.unlink(target)
+                vfs.unlink(target)
             except (IOError, OSError), inst:
                 if inst.errno != errno.ENOENT:
                     raise
@@ -105,9 +107,11 @@
         self.file = opener.open(self.journal, "w")
 
         # a list of ('location', 'path', 'backuppath', cache) entries.
-        # if 'backuppath' is empty, no file existed at backup time
-        # if 'path' is empty, this is a temporary transaction file
-        # (location, and cache are current unused)
+        # - if 'backuppath' is empty, no file existed at backup time
+        # - if 'path' is empty, this is a temporary transaction file
+        # - if 'location' is not empty, the path is outside main opener reach.
+        #   use 'location' value as a key in a vfsmap to find the right 'vfs'
+        # (cache is currently unused)
         self._backupentries = []
         self._backupmap = {}
         self._backupjournal = "%s.backupfiles" % journal
@@ -361,9 +365,10 @@
         self.file.close()
         self._backupsfile.close()
         # cleanup temporary files
-        for _l, f, b, _c in self._backupentries:
-            if not f and b and self.opener.exists(b):
-                self.opener.unlink(b)
+        for l, f, b, _c in self._backupentries:
+            vfs = self._vfsmap[l]
+            if not f and b and vfs.exists(b):
+                vfs.unlink(b)
         self.entries = []
         if self.after:
             self.after()
@@ -372,8 +377,9 @@
         if self.opener.isfile(self._backupjournal):
             self.opener.unlink(self._backupjournal)
             for _l, _f, b, _c in self._backupentries:
-                if b and self.opener.exists(b):
-                    self.opener.unlink(b)
+                vfs = self._vfsmap[l]
+                if b and vfs.exists(b):
+                    vfs.unlink(b)
         self._backupentries = []
         self.journal = None
         # run post close action
@@ -408,7 +414,7 @@
             self.report(_("transaction abort!\n"))
 
             try:
-                _playback(self.journal, self.report, self.opener,
+                _playback(self.journal, self.report, self.opener, self._vfsmap,
                           self.entries, self._backupentries, False)
                 self.report(_("rollback completed\n"))
             except Exception:
@@ -417,7 +423,7 @@
             self.journal = None
 
 
-def rollback(opener, file, report):
+def rollback(opener, vfsmap, file, report):
     """Rolls back the transaction contained in the given file
 
     Reads the entries in the specified file, and the corresponding
@@ -459,4 +465,4 @@
                 report(_("journal was created by a different version of "
                          "Mercurial"))
 
-    _playback(file, report, opener, entries, backupentries)
+    _playback(file, report, opener, vfsmap, entries, backupentries)