Mercurial > hg
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 |