Patchwork [4,of,6,V2] transaction: omit rollbacking a file if filename of it is dropped from map

login
register
mail settings
Submitter Katsunori FUJIWARA
Date Dec. 16, 2015, 5:50 p.m.
Message ID <2f1413cd29a754d41c65.1450288252@feefifofum>
Download mbox | patch
Permalink /patch/12069/
State Superseded
Headers show

Comments

Katsunori FUJIWARA - Dec. 16, 2015, 5:50 p.m.
# HG changeset patch
# User FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
# Date 1450287754 -32400
#      Thu Dec 17 02:42:34 2015 +0900
# Node ID 2f1413cd29a754d41c65f14d162605fc24bdd45c
# Parent  6455d3aac05ac9ab6913b162b46a924b9a512121
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.

Patch

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"))