diff --git a/mercurial/phases.py b/mercurial/phases.py --- a/mercurial/phases.py +++ b/mercurial/phases.py @@ -392,32 +392,44 @@ self._retractboundary(repo, tr, targetphase, delroots) repo.invalidatevolatilesets() - def retractboundary(self, repo, tr, targetphase, nodes): + def retractboundary(self, repo, tr, targetphase, nodes, dryrun=None): oldroots = self.phaseroots[:targetphase + 1] if tr is None: phasetracking = None else: phasetracking = tr.changes.get('phases') repo = repo.unfiltered() - if (self._retractboundary(repo, tr, targetphase, nodes) - and phasetracking is not None): - - # find the affected revisions - new = self.phaseroots[targetphase] - old = oldroots[targetphase] - affected = set(repo.revs('(%ln::) - (%ln::)', new, old)) + changes = [set(), set(), set()] + if dryrun: + getphase = repo._phasecache.phase + nds = [n for n in nodes + if getphase(repo, repo[n].rev()) < targetphase] + targetphroots = oldroots[-1] + affected = set(repo.revs('(%ln::) - (%ln::)', nds, targetphroots)) + for rev in affected: + revphase = getphase(repo, rev) + changes[revphase].update((rev,)) + else: + if (self._retractboundary(repo, tr, targetphase, nodes) + and phasetracking is not None): - # find the phase of the affected revision - for phase in xrange(targetphase, -1, -1): - if phase: - roots = oldroots[phase] - revs = set(repo.revs('%ln::%ld', roots, affected)) - affected -= revs - else: # public phase - revs = affected - for r in revs: - _trackphasechange(phasetracking, r, phase, targetphase) - repo.invalidatevolatilesets() + # find the affected revisions + new = self.phaseroots[targetphase] + old = oldroots[targetphase] + affected = set(repo.revs('(%ln::) - (%ln::)', new, old)) + + # find the phase of the affected revision + for phase in xrange(targetphase, -1, -1): + if phase: + roots = oldroots[phase] + revs = set(repo.revs('%ln::%ld', roots, affected)) + affected -= revs + else: # public phase + revs = affected + for r in revs: + _trackphasechange(phasetracking, r, phase, targetphase) + repo.invalidatevolatilesets() + return changes def _retractboundary(self, repo, tr, targetphase, nodes): # Be careful to preserve shallow-copied values: do not update @@ -489,7 +501,7 @@ phcache.advanceboundary(repo, tr, targetphase, nodes) repo._phasecache.replace(phcache) -def retractboundary(repo, tr, targetphase, nodes): +def retractboundary(repo, tr, targetphase, nodes, dryrun=None): """Set nodes back to a phase changing other nodes phases if necessary. @@ -498,8 +510,11 @@ Simplify boundary to contains phase roots only.""" phcache = repo._phasecache.copy() - phcache.retractboundary(repo, tr, targetphase, nodes) - repo._phasecache.replace(phcache) + changes = phcache.retractboundary(repo, tr, targetphase, nodes, + dryrun=dryrun) + if not dryrun: + repo._phasecache.replace(phcache) + return changes def registernew(repo, tr, targetphase, nodes): """register a new revision and its phase