[PATCH 1 of 2 SPRINT] transaction: omit rollbacking a file if filename of it is dropped from map

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Tue Nov 3 18:13:54 UTC 2015


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1446574170 -32400
#      Wed Nov 04 03:09:30 2015 +0900
# Node ID 9716bacc8e464e9ffaab609a74b9d31c9f93aa24
# Parent  859f453e8b4e2b42b6b6552b79c5c5e7e2fc1cf7
transaction: omit rollbacking a file if filename of it is dropped from map

This functionality is used by subsequent patch to avoid redundant (and
maybe harmful) truncation of '00changelog.i' at transaction failure.

This patch chooses adding '_avoidrollback()' instead of allowing
direct access to 'map' (and/or '_entries'), to hide internal structure
of 'transaction' class.

'_avoidrollback()' can't be decorated by '@active', because it should
be invoked from an abort hook, which is executed after inactivation of
transaction itself.

diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -489,6 +489,16 @@ class transaction(object):
             undobackupfile.write("%s\0%s\0%s\0%d\n" % (l, f, u, c))
         undobackupfile.close()
 
+    def _avoidrollback(self, filename):
+        """Avoid rollbacking the specified file at transaction failure
+
+        This doesn't affect rollbacking via 'rollback()' after
+        committing current transaction, because 'rollback()' gets
+        information to rollback from journal (renamed to 'undo' at
+        that time, actually) file, and it isn't changed by this.
+        """
+        if filename in self.map:
+            del self.map[filename]
 
     def _abort(self):
         self.count = 0
@@ -509,8 +519,12 @@ class transaction(object):
             try:
                 for cat in sorted(self._abortcallback):
                     self._abortcallback[cat](self)
+
+                # a file should be dropped from map, if it doesn't
+                # require any rollbacking procedure
+                entries = [e for e in self.entries if e[0] in self.map]
                 _playback(self.journal, self.report, self.opener, self._vfsmap,
-                          self.entries, self._backupentries, False)
+                          entries, self._backupentries, False)
                 self.report(_("rollback completed\n"))
             except BaseException:
                 self.report(_("rollback failed - please run hg recover\n"))


More information about the Mercurial-devel mailing list