dirstate: try to use hardlink to backup dirstate
This should be more efficient once util.copyfile has real hardlink support.
--- 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