comparison mercurial/dirstate.py @ 47592:0f5c203eb5ab

dirstate: add a function to update tracking status while "moving" parents The `scmutil.dirstateparent` is moving the dirstate parent without touching the working copy. It is used by history-rewriting operations like amending of folding. The function was directly doing the "low level" computation and dirstate change. All that logic belong to the dirstate and should be moved there. For this purpose we introduce a new function that does just that and use it. Differential Revision: https://phab.mercurial-scm.org/D11012
author Pierre-Yves David <pierre-yves.david@octobus.net>
date Sat, 10 Jul 2021 23:31:51 +0200
parents 3d8b639bfbaa
children f927ad5a4e2c
comparison
equal deleted inserted replaced
47591:3d8b639bfbaa 47592:0f5c203eb5ab
68 try: 68 try:
69 return os.fstat(tmpfd)[stat.ST_MTIME] 69 return os.fstat(tmpfd)[stat.ST_MTIME]
70 finally: 70 finally:
71 os.close(tmpfd) 71 os.close(tmpfd)
72 vfs.unlink(tmpname) 72 vfs.unlink(tmpname)
73
74
75 def requires_parents_change(func):
76 def wrap(self, *args, **kwargs):
77 if not self.pendingparentchange():
78 msg = 'calling `%s` outside of a parentchange context'
79 msg %= func.__name__
80 raise error.ProgrammingError(msg)
81 return func(self, *args, **kwargs)
82
83 return wrap
73 84
74 85
75 @interfaceutil.implementer(intdirstate.idirstate) 86 @interfaceutil.implementer(intdirstate.idirstate)
76 class dirstate(object): 87 class dirstate(object):
77 def __init__( 88 def __init__(
437 def copied(self, file): 448 def copied(self, file):
438 return self._map.copymap.get(file, None) 449 return self._map.copymap.get(file, None)
439 450
440 def copies(self): 451 def copies(self):
441 return self._map.copymap 452 return self._map.copymap
453
454 @requires_parents_change
455 def update_file_reference(
456 self,
457 filename,
458 p1_tracked,
459 ):
460 """Set a file as tracked in the parent (or not)
461
462 This is to be called when adjust the dirstate to a new parent after an history
463 rewriting operation.
464
465 It should not be called during a merge (p2 != nullid) and only within
466 a `with dirstate.parentchange():` context.
467 """
468 if self.in_merge:
469 msg = b'update_file_reference should not be called when merging'
470 raise error.ProgrammingError(msg)
471 entry = self._map.get(filename)
472 if entry is None:
473 wc_tracked = False
474 else:
475 wc_tracked = entry.tracked
476 if p1_tracked and wc_tracked:
477 # the underlying reference might have changed, we will have to
478 # check it.
479 self.normallookup(filename)
480 elif not (p1_tracked or wc_tracked):
481 # the file is no longer relevant to anyone
482 self._drop(filename)
483 elif (not p1_tracked) and wc_tracked:
484 if not entry.added:
485 self._add(filename)
486 elif p1_tracked and not wc_tracked:
487 if entry is None or not entry.removed:
488 self._remove(filename)
489 else:
490 assert False, 'unreachable'
442 491
443 def _addpath( 492 def _addpath(
444 self, 493 self,
445 f, 494 f,
446 mode=0, 495 mode=0,