mercurial/phases.py
changeset 45131 61e7464477ac
parent 45117 b1e51ef4e536
child 45356 f025b97f3758
equal deleted inserted replaced
45130:33524b6bef53 45131:61e7464477ac
   168     Return (roots, dirty) where dirty is true if roots differ from
   168     Return (roots, dirty) where dirty is true if roots differ from
   169     what is being stored.
   169     what is being stored.
   170     """
   170     """
   171     repo = repo.unfiltered()
   171     repo = repo.unfiltered()
   172     dirty = False
   172     dirty = False
   173     roots = [set() for i in range(max(allphases) + 1)]
   173     roots = {i: set() for i in allphases}
   174     try:
   174     try:
   175         f, pending = txnutil.trypending(repo.root, repo.svfs, b'phaseroots')
   175         f, pending = txnutil.trypending(repo.root, repo.svfs, b'phaseroots')
   176         try:
   176         try:
   177             for line in f:
   177             for line in f:
   178                 phase, nh = line.split()
   178                 phase, nh = line.split()
   331         repo = repo.unfiltered()
   331         repo = repo.unfiltered()
   332         cl = repo.changelog
   332         cl = repo.changelog
   333         if len(cl) >= self._loadedrevslen:
   333         if len(cl) >= self._loadedrevslen:
   334             self.invalidate()
   334             self.invalidate()
   335             self.loadphaserevs(repo)
   335             self.loadphaserevs(repo)
   336         return any(self.phaseroots[1:])
   336         return any(
       
   337             revs
       
   338             for phase, revs in pycompat.iteritems(self.phaseroots)
       
   339             if phase != public
       
   340         )
   337 
   341 
   338     def nonpublicphaseroots(self, repo):
   342     def nonpublicphaseroots(self, repo):
   339         """returns the roots of all non-public phases
   343         """returns the roots of all non-public phases
   340 
   344 
   341         The roots are not minimized, so if the secret revisions are
   345         The roots are not minimized, so if the secret revisions are
   344         repo = repo.unfiltered()
   348         repo = repo.unfiltered()
   345         cl = repo.changelog
   349         cl = repo.changelog
   346         if len(cl) >= self._loadedrevslen:
   350         if len(cl) >= self._loadedrevslen:
   347             self.invalidate()
   351             self.invalidate()
   348             self.loadphaserevs(repo)
   352             self.loadphaserevs(repo)
   349         return set().union(*[roots for roots in self.phaseroots[1:] if roots])
   353         return set().union(
       
   354             *[
       
   355                 revs
       
   356                 for phase, revs in pycompat.iteritems(self.phaseroots)
       
   357                 if phase != public
       
   358             ]
       
   359         )
   350 
   360 
   351     def getrevset(self, repo, phases, subset=None):
   361     def getrevset(self, repo, phases, subset=None):
   352         """return a smartset for the given phases"""
   362         """return a smartset for the given phases"""
   353         self.loadphaserevs(repo)  # ensure phase's sets are loaded
   363         self.loadphaserevs(repo)  # ensure phase's sets are loaded
   354         phases = set(phases)
   364         phases = set(phases)
   403 
   413 
   404     def copy(self):
   414     def copy(self):
   405         # Shallow copy meant to ensure isolation in
   415         # Shallow copy meant to ensure isolation in
   406         # advance/retractboundary(), nothing more.
   416         # advance/retractboundary(), nothing more.
   407         ph = self.__class__(None, None, _load=False)
   417         ph = self.__class__(None, None, _load=False)
   408         ph.phaseroots = self.phaseroots[:]
   418         ph.phaseroots = self.phaseroots.copy()
   409         ph.dirty = self.dirty
   419         ph.dirty = self.dirty
   410         ph.opener = self.opener
   420         ph.opener = self.opener
   411         ph._loadedrevslen = self._loadedrevslen
   421         ph._loadedrevslen = self._loadedrevslen
   412         ph._phasesets = self._phasesets
   422         ph._phasesets = self._phasesets
   413         return ph
   423         return ph
   423         ):
   433         ):
   424             setattr(self, a, getattr(phcache, a))
   434             setattr(self, a, getattr(phcache, a))
   425 
   435 
   426     def _getphaserevsnative(self, repo):
   436     def _getphaserevsnative(self, repo):
   427         repo = repo.unfiltered()
   437         repo = repo.unfiltered()
   428         nativeroots = []
   438         return repo.changelog.computephases(self.phaseroots)
   429         for phase in trackedphases:
       
   430             nativeroots.append(
       
   431                 pycompat.maplist(repo.changelog.rev, self.phaseroots[phase])
       
   432             )
       
   433         revslen, phasesets = repo.changelog.computephases(nativeroots)
       
   434         phasesets2 = [set() for phase in range(max(allphases) + 1)]
       
   435         for phase, phaseset in zip(allphases, phasesets):
       
   436             phasesets2[phase] = phaseset
       
   437         return revslen, phasesets2
       
   438 
   439 
   439     def _computephaserevspure(self, repo):
   440     def _computephaserevspure(self, repo):
   440         repo = repo.unfiltered()
   441         repo = repo.unfiltered()
   441         cl = repo.changelog
   442         cl = repo.changelog
   442         self._phasesets = [set() for phase in range(max(allphases) + 1)]
   443         self._phasesets = {phase: set() for phase in allphases}
   443         lowerroots = set()
   444         lowerroots = set()
   444         for phase in reversed(trackedphases):
   445         for phase in reversed(trackedphases):
   445             roots = pycompat.maplist(cl.rev, self.phaseroots[phase])
   446             roots = pycompat.maplist(cl.rev, self.phaseroots[phase])
   446             if roots:
   447             if roots:
   447                 ps = set(cl.descendants(roots))
   448                 ps = set(cl.descendants(roots))
   491             self._write(f)
   492             self._write(f)
   492         finally:
   493         finally:
   493             f.close()
   494             f.close()
   494 
   495 
   495     def _write(self, fp):
   496     def _write(self, fp):
   496         for phase, roots in enumerate(self.phaseroots):
   497         for phase, roots in pycompat.iteritems(self.phaseroots):
   497             for h in sorted(roots):
   498             for h in sorted(roots):
   498                 fp.write(b'%i %s\n' % (phase, hex(h)))
   499                 fp.write(b'%i %s\n' % (phase, hex(h)))
   499         self.dirty = False
   500         self.dirty = False
   500 
   501 
   501     def _updateroots(self, phase, newroots, tr):
   502     def _updateroots(self, phase, newroots, tr):
   573                 self._retractboundary(repo, tr, targetphase, delroots)
   574                 self._retractboundary(repo, tr, targetphase, delroots)
   574             repo.invalidatevolatilesets()
   575             repo.invalidatevolatilesets()
   575         return changes
   576         return changes
   576 
   577 
   577     def retractboundary(self, repo, tr, targetphase, nodes):
   578     def retractboundary(self, repo, tr, targetphase, nodes):
   578         oldroots = self.phaseroots[: targetphase + 1]
   579         oldroots = {
       
   580             phase: revs
       
   581             for phase, revs in pycompat.iteritems(self.phaseroots)
       
   582             if phase <= targetphase
       
   583         }
   579         if tr is None:
   584         if tr is None:
   580             phasetracking = None
   585             phasetracking = None
   581         else:
   586         else:
   582             phasetracking = tr.changes.get(b'phases')
   587             phasetracking = tr.changes.get(b'phases')
   583         repo = repo.unfiltered()
   588         repo = repo.unfiltered()
   592             affected = set(repo.revs(b'(%ln::) - (%ln::)', new, old))
   597             affected = set(repo.revs(b'(%ln::) - (%ln::)', new, old))
   593 
   598 
   594             # find the phase of the affected revision
   599             # find the phase of the affected revision
   595             for phase in pycompat.xrange(targetphase, -1, -1):
   600             for phase in pycompat.xrange(targetphase, -1, -1):
   596                 if phase:
   601                 if phase:
   597                     roots = oldroots[phase]
   602                     roots = oldroots.get(phase, [])
   598                     revs = set(repo.revs(b'%ln::%ld', roots, affected))
   603                     revs = set(repo.revs(b'%ln::%ld', roots, affected))
   599                     affected -= revs
   604                     affected -= revs
   600                 else:  # public phase
   605                 else:  # public phase
   601                     revs = affected
   606                     revs = affected
   602                 for r in sorted(revs):
   607                 for r in sorted(revs):
   646 
   651 
   647         Nothing is lost as unknown nodes only hold data for their descendants.
   652         Nothing is lost as unknown nodes only hold data for their descendants.
   648         """
   653         """
   649         filtered = False
   654         filtered = False
   650         has_node = repo.changelog.index.has_node  # to filter unknown nodes
   655         has_node = repo.changelog.index.has_node  # to filter unknown nodes
   651         for phase, nodes in enumerate(self.phaseroots):
   656         for phase, nodes in pycompat.iteritems(self.phaseroots):
   652             missing = sorted(node for node in nodes if not has_node(node))
   657             missing = sorted(node for node in nodes if not has_node(node))
   653             if missing:
   658             if missing:
   654                 for mnode in missing:
   659                 for mnode in missing:
   655                     repo.ui.debug(
   660                     repo.ui.debug(
   656                         b'removing unknown node %s from %i-phase boundary\n'
   661                         b'removing unknown node %s from %i-phase boundary\n'