[PATCH 2 of 5] transaction: prevent addfilegenerator from always making backup

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Fri Oct 9 13:59:26 CDT 2015


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1444416862 -32400
#      Sat Oct 10 03:54:22 2015 +0900
# Node ID b551f3883a6bb1285e83f257b81d10f11ab26341
# Parent  557573b9247d6bac06d253d32105acfec1253604
transaction: prevent addfilegenerator from always making backup

Before this patch, 'addfilegenerator()'-ed files are always backuped
at 'close()', and restored at rollbacking that transaction.

This works fine in many cases, but not in the corner case for
'.hg/dirstate' below:

  1. commit transaction

     At the end of this step, there are two backup files for
     'dirstate': 'undo.dirstate' and 'undo.backup.dirstate'.

  2. update the working directory to the parent not related with ones
     added at (1)

  3. rollback the transaction committed at (1)

     In this case, 'repo.rollback()' explicitly omits restoring
     dirstate from 'undo.dirstate', because the parent of the working
     directory isn't related with rollbacked revisions (= this
     situation is called as not-"parent gone").

     On the other hand, 'transaction.rollback()' restores files from
     'undo.backup.*' forcibly, and this breaks current dirstate.

To prevent 'addfilegenerator()' from always making backup, this patch
adds 'backup' flag to 'addfilegenerator()'.

diff --git a/mercurial/transaction.py b/mercurial/transaction.py
--- a/mercurial/transaction.py
+++ b/mercurial/transaction.py
@@ -249,7 +249,7 @@
 
     @active
     def addfilegenerator(self, genid, filenames, genfunc, order=0,
-                         location=''):
+                         location='', backup=True):
         """add a function to generates some files at transaction commit
 
         The `genfunc` argument is a function capable of generating proper
@@ -271,17 +271,22 @@
         The `location` arguments may be used to indicate the files are located
         outside of the the standard directory for transaction. It should match
         one of the key of the `transaction.vfsmap` dictionary.
+
+        The `backup` argument is used to decide whether original file
+        is backuped at `close()` or not. Backup is used to restore at
+        rollbacking the transaction regardless of rollbacked revisions.
         """
         # For now, we are unable to do proper backup and restore of custom vfs
         # but for bookmarks that are handled outside this mechanism.
-        self._filegenerators[genid] = (order, filenames, genfunc, location)
+        self._filegenerators[genid] = (order, filenames, genfunc, location,
+                                       backup)
 
     def _generatefiles(self, suffix=''):
         # write files registered for generation
         any = False
         for entry in sorted(self._filegenerators.values()):
             any = True
-            order, filenames, genfunc, location = entry
+            order, filenames, genfunc, location, backup = entry
             vfs = self._vfsmap[location]
             files = []
             try:
@@ -289,7 +294,7 @@
                     name += suffix
                     if suffix:
                         self.registertmp(name, location=location)
-                    else:
+                    elif backup:
                         self.addbackup(name, location=location)
                     files.append(vfs(name, 'w', atomictemp=True))
                 genfunc(*files)


More information about the Mercurial-devel mailing list