diff mercurial/transaction.py @ 23904:d251da5e0e84

transaction: include backup file in the "undo" transaction Once the transaction is closed, we now write transaction related data for possible future undo. For now, we only do it for full file "backup" because their were not handle at all in that case. In the future, we could move all the current logic to set undo up (that currently exists in localrepository) inside transaction itself, but it is not strictly requires to solve the current situation.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Fri, 16 Jan 2015 18:34:14 -0800
parents 426607be9c69
children ef22cfff7052
line wrap: on
line diff
--- a/mercurial/transaction.py	Fri Jan 16 19:35:04 2015 -0800
+++ b/mercurial/transaction.py	Fri Jan 16 18:34:14 2015 -0800
@@ -405,6 +405,7 @@
                     self.report("couldn't remote %s: %s\n"
                                 % (vfs.join(b), inst))
         self.entries = []
+        self._writeundo()
         if self.after:
             self.after()
         if self.opener.isfile(self.journal):
@@ -440,6 +441,32 @@
         scope)'''
         self._abort()
 
+    def _writeundo(self):
+        """write transaction data for possible future undo call"""
+        if self.undoname is None:
+            return
+        undobackupfile = self.opener.open("%s.backupfiles" % self.undoname, 'w')
+        undobackupfile.write('%d\n' % version)
+        for l, f, b, c in self._backupentries:
+            if not f:  # temporary file
+                continue
+            if not b:
+                u = ''
+            else:
+                if l not in self._vfsmap and c:
+                    self.report("couldn't remote %s: unknown cache location"
+                                "%s\n" % (b, l))
+                    continue
+                vfs = self._vfsmap[l]
+                base, name = vfs.split(b)
+                assert name.startswith(self.journal), name
+                uname = name.replace(self.journal, self.undoname, 1)
+                u = vfs.reljoin(base, uname)
+                util.copyfile(vfs.join(b), vfs.join(u), hardlink=True)
+            undobackupfile.write("%s\0%s\0%s\0%d\n" % (l, f, u, c))
+        undobackupfile.close()
+
+
     def _abort(self):
         self.count = 0
         self.usages = 0