Show More
@@ -677,15 +677,7 b' class phasecache:' | |||||
677 |
|
677 | |||
678 | def _retractboundary(self, repo, tr, targetphase, nodes=None, revs=None): |
|
678 | def _retractboundary(self, repo, tr, targetphase, nodes=None, revs=None): | |
679 | if targetphase == public: |
|
679 | if targetphase == public: | |
680 |
return |
|
680 | return {} | |
681 | # Be careful to preserve shallow-copied values: do not update |
|
|||
682 | # phaseroots values, replace them. |
|
|||
683 | if revs is None: |
|
|||
684 | revs = [] |
|
|||
685 | if nodes is None: |
|
|||
686 | nodes = [] |
|
|||
687 | if not revs and not nodes: |
|
|||
688 | return False |
|
|||
689 | if ( |
|
681 | if ( | |
690 | targetphase == internal |
|
682 | targetphase == internal | |
691 | and not supportinternal(repo) |
|
683 | and not supportinternal(repo) | |
@@ -695,34 +687,103 b' class phasecache:' | |||||
695 | name = phasenames[targetphase] |
|
687 | name = phasenames[targetphase] | |
696 | msg = b'this repository does not support the %s phase' % name |
|
688 | msg = b'this repository does not support the %s phase' % name | |
697 | raise error.ProgrammingError(msg) |
|
689 | raise error.ProgrammingError(msg) | |
|
690 | assert repo.filtername is None | |||
|
691 | cl = repo.changelog | |||
|
692 | torev = cl.index.rev | |||
|
693 | new_revs = set() | |||
|
694 | if revs is not None: | |||
|
695 | new_revs.update(revs) | |||
|
696 | if nodes is not None: | |||
|
697 | new_revs.update(torev(node) for node in nodes) | |||
|
698 | if not new_revs: # bail out early to avoid the loadphaserevs call | |||
|
699 | return {} # note: why do people call retractboundary with nothing ? | |||
698 |
|
700 | |||
699 | torev = repo.changelog.index.rev |
|
701 | if nullrev in new_revs: | |
|
702 | raise error.Abort(_(b'cannot change null revision phase')) | |||
|
703 | ||||
|
704 | # Compute change in phase roots by walking the graph | |||
|
705 | # | |||
|
706 | # note: If we had a cheap parent β children mapping we could do | |||
|
707 | # something even cheaper/more-bounded | |||
|
708 | # | |||
|
709 | # The idea would be to walk from item in new_revs stopping at | |||
|
710 | # descendant with phases >= target_phase. | |||
|
711 | # | |||
|
712 | # 1) This detect new_revs that are not new_roots (either already >= | |||
|
713 | # target_phase or reachable though another new_revs | |||
|
714 | # 2) This detect replaced current_roots as we reach them | |||
|
715 | # 3) This can avoid walking to the tip if we retract over a small | |||
|
716 | # branch. | |||
|
717 | # | |||
|
718 | # So instead, we do a variation of this, we walk from the smaller new | |||
|
719 | # revision to the tip to avoid missing any potential children. | |||
|
720 | # | |||
|
721 | # The following code would be a good candidate for native code⦠if only | |||
|
722 | # we could knew the phase of a changeset efficiently in native code. | |||
|
723 | parents = cl.parentrevs | |||
|
724 | phase = self.phase | |||
|
725 | new_roots = set() # roots added by this phases | |||
|
726 | changed_revs = {} # revision affected by this call | |||
|
727 | replaced_roots = set() # older roots replaced by this call | |||
700 | currentroots = self._phaseroots[targetphase] |
|
728 | currentroots = self._phaseroots[targetphase] | |
701 | finalroots = oldroots = set(currentroots) |
|
729 | start = min(new_revs) | |
702 | newroots = [torev(node) for node in nodes] + [r for r in revs] |
|
730 | end = len(cl) | |
703 | newroots = [ |
|
731 | rev_phases = [None] * (end - start) | |
704 | rev for rev in newroots if self.phase(repo, rev) < targetphase |
|
732 | for r in range(start, end): | |
705 | ] |
|
|||
706 |
|
733 | |||
707 | if newroots: |
|
734 | # gather information about the current_rev | |
708 | if nullrev in newroots: |
|
735 | r_phase = phase(repo, r) | |
709 | raise error.Abort(_(b'cannot change null revision phase')) |
|
736 | p_phase = None # phase inherited from parents | |
710 | # do not break the CoW assumption of the shallow copy |
|
737 | p1, p2 = parents(r) | |
711 | currentroots = currentroots.copy() |
|
738 | if p1 >= start: | |
712 | currentroots.update(newroots) |
|
739 | p1_phase = rev_phases[p1 - start] | |
|
740 | if p1_phase is not None: | |||
|
741 | p_phase = p1_phase | |||
|
742 | if p2 >= start: | |||
|
743 | p2_phase = rev_phases[p2 - start] | |||
|
744 | if p2_phase is not None: | |||
|
745 | if p_phase is not None: | |||
|
746 | p_phase = max(p_phase, p2_phase) | |||
|
747 | else: | |||
|
748 | p_phase = p2_phase | |||
713 |
|
749 | |||
714 | # Only compute new roots for revs above the roots that are being |
|
750 | # assess the situation | |
715 | # retracted. |
|
751 | if r in new_revs and r_phase < targetphase: | |
716 | minnewroot = min(newroots) |
|
752 | if p_phase is None or p_phase < targetphase: | |
717 | aboveroots = [rev for rev in currentroots if rev >= minnewroot] |
|
753 | new_roots.add(r) | |
718 | updatedroots = repo.revs(b'roots(%ld::)', aboveroots) |
|
754 | rev_phases[r - start] = targetphase | |
|
755 | changed_revs[r] = r_phase | |||
|
756 | elif p_phase is None: | |||
|
757 | rev_phases[r - start] = r_phase | |||
|
758 | else: | |||
|
759 | if p_phase > r_phase: | |||
|
760 | rev_phases[r - start] = p_phase | |||
|
761 | else: | |||
|
762 | rev_phases[r - start] = r_phase | |||
|
763 | if p_phase == targetphase: | |||
|
764 | if p_phase > r_phase: | |||
|
765 | changed_revs[r] = r_phase | |||
|
766 | elif r in currentroots: | |||
|
767 | replaced_roots.add(r) | |||
719 |
|
768 | |||
720 | finalroots = {rev for rev in currentroots if rev < minnewroot} |
|
769 | if new_roots: | |
721 | finalroots.update(updatedroots) |
|
770 | assert changed_revs | |
722 | if finalroots != oldroots: |
|
771 | final_roots = new_roots | currentroots - replaced_roots | |
723 | self._updateroots(repo, targetphase, finalroots, tr) |
|
772 | self._updateroots(repo, targetphase, final_roots, tr) | |
724 | return True |
|
773 | if targetphase > 1: | |
725 | return False |
|
774 | retracted = set(changed_revs) | |
|
775 | for lower_phase in range(1, targetphase): | |||
|
776 | lower_roots = self._phaseroots.get(lower_phase) | |||
|
777 | if lower_roots is None: | |||
|
778 | continue | |||
|
779 | if lower_roots & retracted: | |||
|
780 | simpler_roots = lower_roots - retracted | |||
|
781 | self._updateroots(repo, lower_phase, simpler_roots, tr) | |||
|
782 | return changed_revs | |||
|
783 | else: | |||
|
784 | assert not changed_revs | |||
|
785 | assert not replaced_roots | |||
|
786 | return {} | |||
726 |
|
787 | |||
727 | def register_strip( |
|
788 | def register_strip( | |
728 | self, |
|
789 | self, |
General Comments 0
You need to be logged in to leave comments.
Login now