Show More
@@ -125,10 +125,38 b' def _genrevdescendants(repo, revs, follo' | |||
|
125 | 125 | yield i |
|
126 | 126 | break |
|
127 | 127 | |
|
128 |
def |
|
|
128 | def _builddescendantsmap(repo, startrev, followfirst): | |
|
129 | """Build map of 'rev -> child revs', offset from startrev""" | |
|
130 | cl = repo.changelog | |
|
131 | nullrev = node.nullrev | |
|
132 | descmap = [[] for _rev in xrange(startrev, len(cl))] | |
|
133 | for currev in cl.revs(startrev + 1): | |
|
134 | p1rev, p2rev = cl.parentrevs(currev) | |
|
135 | if p1rev >= startrev: | |
|
136 | descmap[p1rev - startrev].append(currev) | |
|
137 | if not followfirst and p2rev != nullrev and p2rev >= startrev: | |
|
138 | descmap[p2rev - startrev].append(currev) | |
|
139 | return descmap | |
|
140 | ||
|
141 | def _genrevdescendantsofdepth(repo, revs, followfirst, startdepth, stopdepth): | |
|
142 | startrev = revs.min() | |
|
143 | descmap = _builddescendantsmap(repo, startrev, followfirst) | |
|
144 | def pfunc(rev): | |
|
145 | return descmap[rev - startrev] | |
|
146 | return _walkrevtree(pfunc, revs, startdepth, stopdepth, reverse=False) | |
|
147 | ||
|
148 | def revdescendants(repo, revs, followfirst, startdepth=None, stopdepth=None): | |
|
129 | 149 | """Like revlog.descendants() but supports additional options, includes |
|
130 |
the given revs themselves, and returns a smartset |
|
|
131 | gen = _genrevdescendants(repo, revs, followfirst) | |
|
150 | the given revs themselves, and returns a smartset | |
|
151 | ||
|
152 | Scan ends at the stopdepth (exlusive) if specified. Revisions found | |
|
153 | earlier than the startdepth are omitted. | |
|
154 | """ | |
|
155 | if startdepth is None and stopdepth is None: | |
|
156 | gen = _genrevdescendants(repo, revs, followfirst) | |
|
157 | else: | |
|
158 | gen = _genrevdescendantsofdepth(repo, revs, followfirst, | |
|
159 | startdepth, stopdepth) | |
|
132 | 160 | return generatorset(gen, iterasc=True) |
|
133 | 161 | |
|
134 | 162 | def _reachablerootspure(repo, minroot, roots, heads, includepath): |
@@ -595,23 +595,42 b' def desc(repo, subset, x):' | |||
|
595 | 595 | return subset.filter(lambda r: matcher(repo[r].description()), |
|
596 | 596 | condrepr=('<desc %r>', ds)) |
|
597 | 597 | |
|
598 |
def _descendants(repo, subset, x, followfirst=False |
|
|
598 | def _descendants(repo, subset, x, followfirst=False, startdepth=None, | |
|
599 | stopdepth=None): | |
|
599 | 600 | roots = getset(repo, fullreposet(repo), x) |
|
600 | 601 | if not roots: |
|
601 | 602 | return baseset() |
|
602 | s = dagop.revdescendants(repo, roots, followfirst) | |
|
603 | s = dagop.revdescendants(repo, roots, followfirst, startdepth, stopdepth) | |
|
603 | 604 | return subset & s |
|
604 | 605 | |
|
605 | @predicate('descendants(set)', safe=True) | |
|
606 | @predicate('descendants(set[, depth])', safe=True) | |
|
606 | 607 | def descendants(repo, subset, x): |
|
607 | 608 | """Changesets which are descendants of changesets in set, including the |
|
608 | 609 | given changesets themselves. |
|
610 | ||
|
611 | If depth is specified, the result only includes changesets up to | |
|
612 | the specified generation. | |
|
609 | 613 | """ |
|
610 | args = getargsdict(x, 'descendants', 'set') | |
|
614 | # startdepth is for internal use only until we can decide the UI | |
|
615 | args = getargsdict(x, 'descendants', 'set depth startdepth') | |
|
611 | 616 | if 'set' not in args: |
|
612 | 617 | # i18n: "descendants" is a keyword |
|
613 | 618 | raise error.ParseError(_('descendants takes at least 1 argument')) |
|
614 | return _descendants(repo, subset, args['set']) | |
|
619 | startdepth = stopdepth = None | |
|
620 | if 'startdepth' in args: | |
|
621 | n = getinteger(args['startdepth'], | |
|
622 | "descendants expects an integer startdepth") | |
|
623 | if n < 0: | |
|
624 | raise error.ParseError("negative startdepth") | |
|
625 | startdepth = n | |
|
626 | if 'depth' in args: | |
|
627 | # i18n: "descendants" is a keyword | |
|
628 | n = getinteger(args['depth'], _("descendants expects an integer depth")) | |
|
629 | if n < 0: | |
|
630 | raise error.ParseError(_("negative depth")) | |
|
631 | stopdepth = n + 1 | |
|
632 | return _descendants(repo, subset, args['set'], | |
|
633 | startdepth=startdepth, stopdepth=stopdepth) | |
|
615 | 634 | |
|
616 | 635 | @predicate('_firstdescendants', safe=True) |
|
617 | 636 | def _firstdescendants(repo, subset, x): |
@@ -980,6 +980,60 b' test descendants' | |||
|
980 | 980 | 7 |
|
981 | 981 | 8 |
|
982 | 982 | |
|
983 | test descendants with depth limit | |
|
984 | ||
|
985 | (depth=0 selects the node itself) | |
|
986 | ||
|
987 | $ log 'descendants(0, depth=0)' | |
|
988 | 0 | |
|
989 | $ log 'null: & descendants(null, depth=0)' | |
|
990 | -1 | |
|
991 | ||
|
992 | (p2 = null should be ignored) | |
|
993 | ||
|
994 | $ log 'null: & descendants(null, depth=2)' | |
|
995 | -1 | |
|
996 | 0 | |
|
997 | 1 | |
|
998 | ||
|
999 | (multiple paths: depth(6) = (2, 3)) | |
|
1000 | ||
|
1001 | $ log 'descendants(1+3, depth=2)' | |
|
1002 | 1 | |
|
1003 | 2 | |
|
1004 | 3 | |
|
1005 | 4 | |
|
1006 | 5 | |
|
1007 | 6 | |
|
1008 | ||
|
1009 | (multiple paths: depth(5) = (1, 2), depth(6) = (2, 3)) | |
|
1010 | ||
|
1011 | $ log 'descendants(3+1, depth=2, startdepth=2)' | |
|
1012 | 4 | |
|
1013 | 5 | |
|
1014 | 6 | |
|
1015 | ||
|
1016 | (multiple depths: depth(6) = (0, 2, 4), search for depth=2) | |
|
1017 | ||
|
1018 | $ log 'descendants(0+3+6, depth=3, startdepth=1)' | |
|
1019 | 1 | |
|
1020 | 2 | |
|
1021 | 3 | |
|
1022 | 4 | |
|
1023 | 5 | |
|
1024 | 6 | |
|
1025 | 7 | |
|
1026 | ||
|
1027 | (multiple depths: depth(6) = (0, 4), no match) | |
|
1028 | ||
|
1029 | $ log 'descendants(0+6, depth=3, startdepth=1)' | |
|
1030 | 1 | |
|
1031 | 2 | |
|
1032 | 3 | |
|
1033 | 4 | |
|
1034 | 5 | |
|
1035 | 7 | |
|
1036 | ||
|
983 | 1037 | test author |
|
984 | 1038 | |
|
985 | 1039 | $ log 'author(bob)' |
General Comments 0
You need to be logged in to leave comments.
Login now