Mercurial > hg
changeset 34940:c2b30348930f stable
dirstate: clean up when restoring identical backups
When a dirstate backup is restored, it is possible that no actual changes to
the dirstate have been made. In this case, the backup is still a hardlink
to the original dirstate.
Unfortunately, `os.rename` silently fails (nothing happens, and no error
occurs) when `src` and `dst` are hardlinks to the same file. As a result,
the backup is left lying around. Over time, these files accumulate.
When restoring dirstate backups, check if the backup and the dirstate are
the same file, and if so, just delete the backup.
Differential Revision: https://phab.mercurial-scm.org/D1201
author | Mark Thomas <mbthomas@fb.com> |
---|---|
date | Fri, 20 Oct 2017 05:53:35 -0700 |
parents | 2c80a864e83e |
children | 37450a122128 |
files | mercurial/dirstate.py tests/test-dirstate-backup.t |
diffstat | 2 files changed, 6 insertions(+), 3 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/dirstate.py Fri Oct 20 05:53:33 2017 -0700 +++ b/mercurial/dirstate.py Fri Oct 20 05:53:35 2017 -0700 @@ -1187,7 +1187,11 @@ # changes of dirstate out after restoring from backup file self.invalidate() filename = self._actualfilename(tr) - self._opener.rename(backupname, filename, checkambig=True) + o = self._opener + if util.samefile(o.join(backupname), o.join(filename)): + o.unlink(backupname) + else: + o.rename(backupname, filename, checkambig=True) def clearbackup(self, tr, backupname): '''Clear backup file'''
--- a/tests/test-dirstate-backup.t Fri Oct 20 05:53:33 2017 -0700 +++ b/tests/test-dirstate-backup.t Fri Oct 20 05:53:35 2017 -0700 @@ -11,9 +11,8 @@ abort: stdin: no diffs found [255] -A dirstate backup is left behind +No dirstate backups are left behind $ ls .hg/dirstate* | sort .hg/dirstate - .hg/dirstate.backup.import.* (glob)