Same logic as for set_untracked this make sure both implementation are aligned.
The reset_state implementation for the Rust wrapped had signicantly diverged,
this change finally put it back in line.
| Alphare |
| hg-reviewers |
Same logic as for set_untracked this make sure both implementation are aligned.
The reset_state implementation for the Rust wrapped had signicantly diverged,
this change finally put it back in line.
| Automatic diff as part of commit; lint not applicable. |
| Automatic diff as part of commit; unit tests not applicable. |
| Path | Packages | |||
|---|---|---|---|---|
| M | mercurial/dirstatemap.py (217 lines) |
| Status | Author | Revision | |
|---|---|---|---|
| Closed | SimonSapin | ||
| Closed | SimonSapin | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Abandoned | pulkit | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute | ||
| Closed | marmoute |
| else: | else: | ||||
| self._dirs_decr(f, old_entry=entry, remove_variant=not entry.added) | self._dirs_decr(f, old_entry=entry, remove_variant=not entry.added) | ||||
| if not entry.merged: | if not entry.merged: | ||||
| self.copymap.pop(f, None) | self.copymap.pop(f, None) | ||||
| entry.set_untracked() | entry.set_untracked() | ||||
| self._refresh_entry(f, entry) | self._refresh_entry(f, entry) | ||||
| return True | return True | ||||
| def reset_state( | |||||
| self, | |||||
| filename, | |||||
| wc_tracked=False, | |||||
| p1_tracked=False, | |||||
| p2_tracked=False, | |||||
| merged=False, | |||||
| clean_p1=False, | |||||
| clean_p2=False, | |||||
| possibly_dirty=False, | |||||
| parentfiledata=None, | |||||
| ): | |||||
| """Set a entry to a given state, diregarding all previous state | |||||
| This is to be used by the part of the dirstate API dedicated to | |||||
| adjusting the dirstate after a update/merge. | |||||
| note: calling this might result to no entry existing at all if the | |||||
| dirstate map does not see any point at having one for this file | |||||
| anymore. | |||||
| """ | |||||
| if merged and (clean_p1 or clean_p2): | |||||
| msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |||||
| raise error.ProgrammingError(msg) | |||||
| # copy information are now outdated | |||||
| # (maybe new information should be in directly passed to this function) | |||||
| self.copymap.pop(filename, None) | |||||
| if not (p1_tracked or p2_tracked or wc_tracked): | |||||
| old_entry = self._map.get(filename) | |||||
| self._drop_entry(filename) | |||||
| self._dirs_decr(filename, old_entry=old_entry) | |||||
| return | |||||
| elif merged: | |||||
| pass | |||||
| elif not (p1_tracked or p2_tracked) and wc_tracked: | |||||
| pass # file is added, nothing special to adjust | |||||
| elif (p1_tracked or p2_tracked) and not wc_tracked: | |||||
| pass | |||||
| elif clean_p2 and wc_tracked: | |||||
| pass | |||||
| elif not p1_tracked and p2_tracked and wc_tracked: | |||||
| clean_p2 = True | |||||
| elif possibly_dirty: | |||||
| pass | |||||
| elif wc_tracked: | |||||
| # this is a "normal" file | |||||
| if parentfiledata is None: | |||||
| msg = b'failed to pass parentfiledata for a normal file: %s' | |||||
| msg %= filename | |||||
| raise error.ProgrammingError(msg) | |||||
| else: | |||||
| assert False, 'unreachable' | |||||
| old_entry = self._map.get(filename) | |||||
| self._dirs_incr(filename, old_entry) | |||||
| entry = DirstateItem( | |||||
| wc_tracked=wc_tracked, | |||||
| p1_tracked=p1_tracked, | |||||
| p2_tracked=p2_tracked, | |||||
| merged=merged, | |||||
| clean_p1=clean_p1, | |||||
| clean_p2=clean_p2, | |||||
| possibly_dirty=possibly_dirty, | |||||
| parentfiledata=parentfiledata, | |||||
| ) | |||||
| self._insert_entry(filename, entry) | |||||
| class dirstatemap(_dirstatemapcommon): | class dirstatemap(_dirstatemapcommon): | ||||
| """Map encapsulating the dirstate's contents. | """Map encapsulating the dirstate's contents. | ||||
| The dirstate contains the following state: | The dirstate contains the following state: | ||||
| - `identity` is the identity of the dirstate file, which can be used to | - `identity` is the identity of the dirstate file, which can be used to | ||||
| detect when changes have occurred to the dirstate file. | detect when changes have occurred to the dirstate file. | ||||
| def _refresh_entry(self, f, entry): | def _refresh_entry(self, f, entry): | ||||
| if not entry.any_tracked: | if not entry.any_tracked: | ||||
| self._map.pop(f, None) | self._map.pop(f, None) | ||||
| def _insert_entry(self, f, entry): | def _insert_entry(self, f, entry): | ||||
| self._map[f] = entry | self._map[f] = entry | ||||
| def reset_state( | |||||
| self, | |||||
| filename, | |||||
| wc_tracked=False, | |||||
| p1_tracked=False, | |||||
| p2_tracked=False, | |||||
| merged=False, | |||||
| clean_p1=False, | |||||
| clean_p2=False, | |||||
| possibly_dirty=False, | |||||
| parentfiledata=None, | |||||
| ): | |||||
| """Set a entry to a given state, diregarding all previous state | |||||
| This is to be used by the part of the dirstate API dedicated to | |||||
| adjusting the dirstate after a update/merge. | |||||
| note: calling this might result to no entry existing at all if the | |||||
| dirstate map does not see any point at having one for this file | |||||
| anymore. | |||||
| """ | |||||
| if merged and (clean_p1 or clean_p2): | |||||
| msg = b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |||||
| raise error.ProgrammingError(msg) | |||||
| # copy information are now outdated | |||||
| # (maybe new information should be in directly passed to this function) | |||||
| self.copymap.pop(filename, None) | |||||
| if not (p1_tracked or p2_tracked or wc_tracked): | |||||
| old_entry = self._map.pop(filename, None) | |||||
| self._dirs_decr(filename, old_entry=old_entry) | |||||
| self.copymap.pop(filename, None) | |||||
| return | |||||
| elif merged: | |||||
| pass | |||||
| elif not (p1_tracked or p2_tracked) and wc_tracked: | |||||
| pass # file is added, nothing special to adjust | |||||
| elif (p1_tracked or p2_tracked) and not wc_tracked: | |||||
| pass | |||||
| elif clean_p2 and wc_tracked: | |||||
| pass | |||||
| elif not p1_tracked and p2_tracked and wc_tracked: | |||||
| clean_p2 = True | |||||
| elif possibly_dirty: | |||||
| pass | |||||
| elif wc_tracked: | |||||
| # this is a "normal" file | |||||
| if parentfiledata is None: | |||||
| msg = b'failed to pass parentfiledata for a normal file: %s' | |||||
| msg %= filename | |||||
| raise error.ProgrammingError(msg) | |||||
| else: | |||||
| assert False, 'unreachable' | |||||
| old_entry = self._map.get(filename) | |||||
| self._dirs_incr(filename, old_entry) | |||||
| entry = DirstateItem( | |||||
| wc_tracked=wc_tracked, | |||||
| p1_tracked=p1_tracked, | |||||
| p2_tracked=p2_tracked, | |||||
| merged=merged, | |||||
| clean_p1=clean_p1, | |||||
| clean_p2=clean_p2, | |||||
| possibly_dirty=possibly_dirty, | |||||
| parentfiledata=parentfiledata, | |||||
| ) | |||||
| self._map[filename] = entry | |||||
| def _drop_entry(self, f): | def _drop_entry(self, f): | ||||
| self._map.pop(f, None) | self._map.pop(f, None) | ||||
| self._copymap.pop(f, None) | self.copymap.pop(f, None) | ||||
| if rustmod is not None: | if rustmod is not None: | ||||
| class dirstatemap(_dirstatemapcommon): | class dirstatemap(_dirstatemapcommon): | ||||
| def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2): | def __init__(self, ui, opener, root, nodeconstants, use_dirstate_v2): | ||||
| super(dirstatemap, self).__init__( | super(dirstatemap, self).__init__( | ||||
| ui, opener, root, nodeconstants, use_dirstate_v2 | ui, opener, root, nodeconstants, use_dirstate_v2 | ||||
| def _drop_entry(self, f): | def _drop_entry(self, f): | ||||
| self._map.drop_item_and_copy_source(f) | self._map.drop_item_and_copy_source(f) | ||||
| def __setitem__(self, key, value): | def __setitem__(self, key, value): | ||||
| assert isinstance(value, DirstateItem) | assert isinstance(value, DirstateItem) | ||||
| self._map.set_dirstate_item(key, value) | self._map.set_dirstate_item(key, value) | ||||
| def reset_state( | |||||
| self, | |||||
| filename, | |||||
| wc_tracked=False, | |||||
| p1_tracked=False, | |||||
| p2_tracked=False, | |||||
| merged=False, | |||||
| clean_p1=False, | |||||
| clean_p2=False, | |||||
| possibly_dirty=False, | |||||
| parentfiledata=None, | |||||
| ): | |||||
| """Set a entry to a given state, disregarding all previous state | |||||
| This is to be used by the part of the dirstate API dedicated to | |||||
| adjusting the dirstate after a update/merge. | |||||
| note: calling this might result to no entry existing at all if the | |||||
| dirstate map does not see any point at having one for this file | |||||
| anymore. | |||||
| """ | |||||
| if merged and (clean_p1 or clean_p2): | |||||
| msg = ( | |||||
| b'`merged` argument incompatible with `clean_p1`/`clean_p2`' | |||||
| ) | |||||
| raise error.ProgrammingError(msg) | |||||
| # copy information are now outdated | |||||
| # (maybe new information should be in directly passed to this function) | |||||
| self.copymap.pop(filename, None) | |||||
| if not (p1_tracked or p2_tracked or wc_tracked): | |||||
| self._map.drop_item_and_copy_source(filename) | |||||
| elif merged: | |||||
| # XXX might be merged and removed ? | |||||
| entry = self.get(filename) | |||||
| if entry is not None and entry.tracked: | |||||
| # XXX mostly replicate dirstate.other parent. We should get | |||||
| # the higher layer to pass us more reliable data where `merged` | |||||
| # actually mean merged. Dropping the else clause will show | |||||
| # failure in `test-graft.t` | |||||
| self.addfile(filename, merged=True) | |||||
| else: | |||||
| self.addfile(filename, from_p2=True) | |||||
| elif not (p1_tracked or p2_tracked) and wc_tracked: | |||||
| self.addfile( | |||||
| filename, added=True, possibly_dirty=possibly_dirty | |||||
| ) | |||||
| elif (p1_tracked or p2_tracked) and not wc_tracked: | |||||
| # XXX might be merged and removed ? | |||||
| self[filename] = DirstateItem.from_v1_data(b'r', 0, 0, 0) | |||||
| elif clean_p2 and wc_tracked: | |||||
| if p1_tracked or self.get(filename) is not None: | |||||
| # XXX the `self.get` call is catching some case in | |||||
| # `test-merge-remove.t` where the file is tracked in p1, the | |||||
| # p1_tracked argument is False. | |||||
| # | |||||
| # In addition, this seems to be a case where the file is marked | |||||
| # as merged without actually being the result of a merge | |||||
| # action. So thing are not ideal here. | |||||
| self.addfile(filename, merged=True) | |||||
| else: | |||||
| self.addfile(filename, from_p2=True) | |||||
| elif not p1_tracked and p2_tracked and wc_tracked: | |||||
| self.addfile( | |||||
| filename, from_p2=True, possibly_dirty=possibly_dirty | |||||
| ) | |||||
| elif possibly_dirty: | |||||
| self.addfile(filename, possibly_dirty=possibly_dirty) | |||||
| elif wc_tracked: | |||||
| # this is a "normal" file | |||||
| if parentfiledata is None: | |||||
| msg = b'failed to pass parentfiledata for a normal file: %s' | |||||
| msg %= filename | |||||
| raise error.ProgrammingError(msg) | |||||
| mode, size, mtime = parentfiledata | |||||
| self.addfile(filename, mode=mode, size=size, mtime=mtime) | |||||
| else: | |||||
| assert False, 'unreachable' | |||||
| ### Legacy method we need to get rid of | ### Legacy method we need to get rid of | ||||
| def addfile( | def addfile( | ||||
| self, | self, | ||||
| f, | f, | ||||
| mode=0, | mode=0, | ||||
| size=None, | size=None, | ||||
| mtime=None, | mtime=None, | ||||