comparison mercurial/dirstatemap.py @ 50081:9a0778bbae6a

dirstate: explicitly backup the datafile Since the transaction does not know about this file, we need to explicitly mark it for backup before touching it.
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Thu, 16 Feb 2023 10:43:22 +0100
parents 302dd8ae2745
children 0f0880c8a7e5
comparison
equal deleted inserted replaced
50080:2a46555c5522 50081:9a0778bbae6a
114 new_docket = docketmod.DirstateDocket.with_new_uuid( 114 new_docket = docketmod.DirstateDocket.with_new_uuid(
115 self.parents(), len(packed), meta 115 self.parents(), len(packed), meta
116 ) 116 )
117 data_filename = new_docket.data_filename() 117 data_filename = new_docket.data_filename()
118 self._opener.write(data_filename, packed) 118 self._opener.write(data_filename, packed)
119 # tell the transaction that we are adding a new file
120 if tr is not None:
121 tr.addbackup(data_filename, location=b'plain')
119 # Write the new docket after the new data file has been 122 # Write the new docket after the new data file has been
120 # written. Because `st` was opened with `atomictemp=True`, 123 # written. Because `st` was opened with `atomictemp=True`,
121 # the actual `.hg/dirstate` file is only affected on close. 124 # the actual `.hg/dirstate` file is only affected on close.
122 st.write(new_docket.serialize()) 125 st.write(new_docket.serialize())
123 st.close() 126 st.close()
124 # Remove the old data file after the new docket pointing to 127 # Remove the old data file after the new docket pointing to
125 # the new data file was written. 128 # the new data file was written.
126 if old_docket.uuid: 129 if old_docket.uuid:
127 data_filename = old_docket.data_filename() 130 data_filename = old_docket.data_filename()
131 if tr is not None:
132 tr.addbackup(data_filename, location=b'plain')
128 unlink = lambda _tr=None: self._opener.unlink(data_filename) 133 unlink = lambda _tr=None: self._opener.unlink(data_filename)
129 if tr: 134 if tr:
130 category = b"dirstate-v2-clean-" + old_docket.uuid 135 category = b"dirstate-v2-clean-" + old_docket.uuid
131 tr.addpostclose(category, unlink) 136 tr.addpostclose(category, unlink)
132 else: 137 else:
610 can_append = self.docket.uuid is not None 615 can_append = self.docket.uuid is not None
611 packed, meta, append = self._map.write_v2(can_append) 616 packed, meta, append = self._map.write_v2(can_append)
612 if append: 617 if append:
613 docket = self.docket 618 docket = self.docket
614 data_filename = docket.data_filename() 619 data_filename = docket.data_filename()
620 # We mark it for backup to make sure a future `hg rollback` (or
621 # `hg recover`?) call find the data it needs to restore a
622 # working repository.
623 #
624 # The backup can use a hardlink because the format is resistant
625 # to trailing "dead" data.
626 if tr is not None:
627 tr.addbackup(data_filename, location=b'plain')
615 with self._opener(data_filename, b'r+b') as fp: 628 with self._opener(data_filename, b'r+b') as fp:
616 fp.seek(docket.data_size) 629 fp.seek(docket.data_size)
617 assert fp.tell() == docket.data_size 630 assert fp.tell() == docket.data_size
618 written = fp.write(packed) 631 written = fp.write(packed)
619 if written is not None: # py2 may return None 632 if written is not None: # py2 may return None