dirstate: handle missing backup file on restoration
This is the stable counter part to e358f6e0e50e.
Since 6.4 will stop writing undo.dirstate in some case (actually… at all), a
transaction created with 6.4 and recover/rolledback with 6.3 need to work to a
certain degreee. This changeset add the necessary bits so that we don't get a
traceback from 6..3 in this cases.
--- a/mercurial/dirstate.py Tue Feb 14 11:56:02 2023 -0500
+++ b/mercurial/dirstate.py Fri Feb 17 14:00:39 2023 +0100
@@ -1444,6 +1444,9 @@
"""return a filename to backup a data-file or None"""
if not self._use_dirstate_v2:
return None
+ if self._map.docket.uuid is None:
+ # not created yet, nothing to backup
+ return None
data_filename = self._map.docket.data_filename()
return data_filename, self.data_backup_filename(backupname)
@@ -1514,10 +1517,23 @@
# this "invalidate()" prevents "wlock.release()" from writing
# changes of dirstate out after restoring from backup file
self.invalidate()
+ o = self._opener
+ if not o.exists(backupname):
+ # there was no file backup, delete existing files
+ filename = self._actualfilename(tr)
+ data_file = None
+ if self._use_dirstate_v2 and self._map.docket.uuid is not None:
+ data_file = self._map.docket.data_filename()
+ if o.exists(filename):
+ o.unlink(filename)
+ if data_file is not None and o.exists(data_file):
+ o.unlink(data_file)
+ return
filename = self._actualfilename(tr)
- o = self._opener
data_pair = self.backup_data_file(backupname)
- if util.samefile(o.join(backupname), o.join(filename)):
+ if o.exists(filename) and util.samefile(
+ o.join(backupname), o.join(filename)
+ ):
o.unlink(backupname)
else:
o.rename(backupname, filename, checkambig=True)
@@ -1534,11 +1550,11 @@
def clearbackup(self, tr, backupname):
'''Clear backup file'''
o = self._opener
- data_backup = self.backup_data_file(backupname)
- o.unlink(backupname)
-
- if data_backup is not None:
- o.unlink(data_backup[0])
+ if o.exists(backupname):
+ data_backup = self.backup_data_file(backupname)
+ o.unlink(backupname)
+ if data_backup is not None:
+ o.unlink(data_backup[0])
def verify(self, m1, m2):
"""check the dirstate content again the parent manifest and yield errors"""