577 reachable.add(p) |
577 reachable.add(p) |
578 visit.append(p) |
578 visit.append(p) |
579 return reachable |
579 return reachable |
580 |
580 |
581 def ancestors(self, *revs): |
581 def ancestors(self, *revs): |
582 'Generate the ancestors of revs using a breadth-first visit' |
582 """Generate the ancestors of 'revs' in reverse topological order. |
|
583 |
|
584 Yield a sequence of revision numbers starting with the parents |
|
585 of each revision in revs, i.e., each revision is *not* considered |
|
586 an ancestor of itself. Results are in breadth-first order: |
|
587 parents of each rev in revs, then parents of those, etc. Result |
|
588 does not include the null revision.""" |
583 visit = list(revs) |
589 visit = list(revs) |
584 seen = set([nullrev]) |
590 seen = set([nullrev]) |
585 while visit: |
591 while visit: |
586 for parent in self.parentrevs(visit.pop(0)): |
592 for parent in self.parentrevs(visit.pop(0)): |
587 if parent not in seen: |
593 if parent not in seen: |
588 visit.append(parent) |
594 visit.append(parent) |
589 seen.add(parent) |
595 seen.add(parent) |
590 yield parent |
596 yield parent |
591 |
597 |
592 def descendants(self, *revs): |
598 def descendants(self, *revs): |
593 'Generate the descendants of revs in topological order' |
599 """Generate the descendants of 'revs' in revision order. |
|
600 |
|
601 Yield a sequence of revision numbers starting with a child of |
|
602 some rev in revs, i.e., each revision is *not* considered a |
|
603 descendant of itself. Results are ordered by revision number (a |
|
604 topological sort).""" |
594 seen = set(revs) |
605 seen = set(revs) |
595 for i in xrange(min(revs) + 1, len(self)): |
606 for i in xrange(min(revs) + 1, len(self)): |
596 for x in self.parentrevs(i): |
607 for x in self.parentrevs(i): |
597 if x != nullrev and x in seen: |
608 if x != nullrev and x in seen: |
598 seen.add(i) |
609 seen.add(i) |
599 yield i |
610 yield i |
600 break |
611 break |
601 |
612 |
602 def findmissing(self, common=None, heads=None): |
613 def findmissing(self, common=None, heads=None): |
603 ''' |
614 """Return the ancestors of heads that are not ancestors of common. |
604 returns the topologically sorted list of nodes from the set: |
615 |
605 missing = (ancestors(heads) \ ancestors(common)) |
616 More specifically, return a list of nodes N such that every N |
606 |
617 satisfies the following constraints: |
607 where ancestors() is the set of ancestors from heads, heads included |
618 |
608 |
619 1. N is an ancestor of some node in 'heads' |
609 if heads is None, the heads of the revlog are used |
620 2. N is not an ancestor of any node in 'common' |
610 if common is None, nullid is assumed to be a common node |
621 |
611 ''' |
622 The list is sorted by revision number, meaning it is |
|
623 topologically sorted. |
|
624 |
|
625 'heads' and 'common' are both lists of node IDs. If heads is |
|
626 not supplied, uses all of the revlog's heads. If common is not |
|
627 supplied, uses nullid.""" |
612 if common is None: |
628 if common is None: |
613 common = [nullid] |
629 common = [nullid] |
614 if heads is None: |
630 if heads is None: |
615 heads = self.heads() |
631 heads = self.heads() |
616 |
632 |
637 missing = list(missing) |
653 missing = list(missing) |
638 missing.sort() |
654 missing.sort() |
639 return [self.node(r) for r in missing] |
655 return [self.node(r) for r in missing] |
640 |
656 |
641 def nodesbetween(self, roots=None, heads=None): |
657 def nodesbetween(self, roots=None, heads=None): |
642 """Return a tuple containing three elements. Elements 1 and 2 contain |
658 """Return a topological path from 'roots' to 'heads'. |
643 a final list bases and heads after all the unreachable ones have been |
659 |
644 pruned. Element 0 contains a topologically sorted list of all |
660 Return a tuple (nodes, outroots, outheads) where 'nodes' is a |
645 |
661 topologically sorted list of all nodes N that satisfy both of |
646 nodes that satisfy these constraints: |
662 these constraints: |
647 1. All nodes must be descended from a node in roots (the nodes on |
663 |
648 roots are considered descended from themselves). |
664 1. N is a descendant of some node in 'roots' |
649 2. All nodes must also be ancestors of a node in heads (the nodes in |
665 2. N is an ancestor of some node in 'heads' |
650 heads are considered to be their own ancestors). |
666 |
651 |
667 Every node is considered to be both a descendant and an ancestor |
652 If roots is unspecified, nullid is assumed as the only root. |
668 of itself, so every reachable node in 'roots' and 'heads' will be |
653 If heads is unspecified, it is taken to be the output of the |
669 included in 'nodes'. |
654 heads method (i.e. a list of all nodes in the repository that |
670 |
655 have no children).""" |
671 'outroots' is the list of reachable nodes in 'roots', i.e., the |
|
672 subset of 'roots' that is returned in 'nodes'. Likewise, |
|
673 'outheads' is the subset of 'heads' that is also in 'nodes'. |
|
674 |
|
675 'roots' and 'heads' are both lists of node IDs. If 'roots' is |
|
676 unspecified, uses nullid as the only root. If 'heads' is |
|
677 unspecified, uses list of all of the revlog's heads.""" |
656 nonodes = ([], [], []) |
678 nonodes = ([], [], []) |
657 if roots is not None: |
679 if roots is not None: |
658 roots = list(roots) |
680 roots = list(roots) |
659 if not roots: |
681 if not roots: |
660 return nonodes |
682 return nonodes |