dirstate: try to use hardlink to backup dirstate
authorJun Wu <quark@fb.com>
Wed, 01 Mar 2017 17:59:21 -0800
changeset 31217 1ef37b16b8e8
parent 31216 49e5491ed9bd
child 31218 fc57a8b95f1b
dirstate: try to use hardlink to backup dirstate This should be more efficient once util.copyfile has real hardlink support.
mercurial/dirstate.py
tests/test-largefiles-small-disk.t
--- a/mercurial/dirstate.py	Sun Mar 05 16:20:07 2017 -0800
+++ b/mercurial/dirstate.py	Wed Mar 01 17:59:21 2017 -0800
@@ -1235,8 +1235,14 @@
             # end of this transaction
             tr.registertmp(filename, location='plain')
 
-        self._opener.write(prefix + self._filename + suffix,
-                           self._opener.tryread(filename))
+        backupname = prefix + self._filename + suffix
+        assert backupname != filename
+        if self._opener.exists(backupname):
+            self._opener.unlink(backupname)
+        # hardlink backup is okay because _writedirstate is always called
+        # with an "atomictemp=True" file.
+        util.copyfile(self._opener.join(filename),
+                      self._opener.join(backupname), hardlink=True)
 
     def restorebackup(self, tr, suffix='', prefix=''):
         '''Restore dirstate by backup file with suffix'''
--- a/tests/test-largefiles-small-disk.t	Sun Mar 05 16:20:07 2017 -0800
+++ b/tests/test-largefiles-small-disk.t	Wed Mar 01 17:59:21 2017 -0800
@@ -5,7 +5,11 @@
   > from mercurial import util
   > #
   > # this makes the original largefiles code abort:
+  > _origcopyfileobj = shutil.copyfileobj
   > def copyfileobj(fsrc, fdst, length=16*1024):
+  >     # allow journal files (used by transaction) to be written
+  >     if 'journal.' in fdst.name:
+  >         return _origcopyfileobj(fsrc, fdst, length)
   >     fdst.write(fsrc.read(4))
   >     raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
   > shutil.copyfileobj = copyfileobj