Show More
@@ -20,11 +20,19 b' from . import (' | |||||
20 | baseset = smartset.baseset |
|
20 | baseset = smartset.baseset | |
21 | generatorset = smartset.generatorset |
|
21 | generatorset = smartset.generatorset | |
22 |
|
22 | |||
23 | def _genrevancestors(repo, revs, followfirst): |
|
23 | # possible maximum depth between null and wdir() | |
|
24 | _maxlogdepth = 0x80000000 | |||
|
25 | ||||
|
26 | def _genrevancestors(repo, revs, followfirst, stopdepth): | |||
24 | if followfirst: |
|
27 | if followfirst: | |
25 | cut = 1 |
|
28 | cut = 1 | |
26 | else: |
|
29 | else: | |
27 | cut = None |
|
30 | cut = None | |
|
31 | if stopdepth is None: | |||
|
32 | stopdepth = _maxlogdepth | |||
|
33 | if stopdepth <= 0: | |||
|
34 | return | |||
|
35 | ||||
28 | cl = repo.changelog |
|
36 | cl = repo.changelog | |
29 |
|
37 | |||
30 | # load input revs lazily to heap so earlier revisions can be yielded |
|
38 | # load input revs lazily to heap so earlier revisions can be yielded | |
@@ -45,10 +53,12 b' def _genrevancestors(repo, revs, followf' | |||||
45 | inputrev = next(irevs, None) |
|
53 | inputrev = next(irevs, None) | |
46 | if inputrev is not None: |
|
54 | if inputrev is not None: | |
47 | heapq.heappush(pendingheap, (-inputrev, 0)) |
|
55 | heapq.heappush(pendingheap, (-inputrev, 0)) | |
48 |
|
|
56 | foundnew = (currev != lastrev) | |
|
57 | if foundnew: | |||
49 | lastrev = currev |
|
58 | lastrev = currev | |
50 | yield currev |
|
59 | yield currev | |
51 |
|
|
60 | pdepth = curdepth + 1 | |
|
61 | if foundnew and pdepth < stopdepth: | |||
52 | try: |
|
62 | try: | |
53 | for prev in cl.parentrevs(currev)[:cut]: |
|
63 | for prev in cl.parentrevs(currev)[:cut]: | |
54 | if prev != node.nullrev: |
|
64 | if prev != node.nullrev: | |
@@ -58,9 +68,13 b' def _genrevancestors(repo, revs, followf' | |||||
58 | if pctx.rev() != node.nullrev: |
|
68 | if pctx.rev() != node.nullrev: | |
59 | heapq.heappush(pendingheap, (-pctx.rev(), pdepth)) |
|
69 | heapq.heappush(pendingheap, (-pctx.rev(), pdepth)) | |
60 |
|
70 | |||
61 | def revancestors(repo, revs, followfirst): |
|
71 | def revancestors(repo, revs, followfirst, stopdepth=None): | |
62 |
"""Like revlog.ancestors(), but supports |
|
72 | """Like revlog.ancestors(), but supports additional options, includes | |
63 | gen = _genrevancestors(repo, revs, followfirst) |
|
73 | the given revs themselves, and returns a smartset | |
|
74 | ||||
|
75 | Scan ends at the stopdepth (exlusive) if specified. | |||
|
76 | """ | |||
|
77 | gen = _genrevancestors(repo, revs, followfirst, stopdepth) | |||
64 | return generatorset(gen, iterasc=False) |
|
78 | return generatorset(gen, iterasc=False) | |
65 |
|
79 | |||
66 | def revdescendants(repo, revs, followfirst): |
|
80 | def revdescendants(repo, revs, followfirst): |
@@ -238,23 +238,33 b' def ancestor(repo, subset, x):' | |||||
238 | return baseset([anc.rev()]) |
|
238 | return baseset([anc.rev()]) | |
239 | return baseset() |
|
239 | return baseset() | |
240 |
|
240 | |||
241 | def _ancestors(repo, subset, x, followfirst=False): |
|
241 | def _ancestors(repo, subset, x, followfirst=False, stopdepth=None): | |
242 | heads = getset(repo, fullreposet(repo), x) |
|
242 | heads = getset(repo, fullreposet(repo), x) | |
243 | if not heads: |
|
243 | if not heads: | |
244 | return baseset() |
|
244 | return baseset() | |
245 | s = dagop.revancestors(repo, heads, followfirst) |
|
245 | s = dagop.revancestors(repo, heads, followfirst, stopdepth) | |
246 | return subset & s |
|
246 | return subset & s | |
247 |
|
247 | |||
248 | @predicate('ancestors(set)', safe=True) |
|
248 | @predicate('ancestors(set[, depth])', safe=True) | |
249 | def ancestors(repo, subset, x): |
|
249 | def ancestors(repo, subset, x): | |
250 | """Changesets that are ancestors of changesets in set, including the |
|
250 | """Changesets that are ancestors of changesets in set, including the | |
251 | given changesets themselves. |
|
251 | given changesets themselves. | |
|
252 | ||||
|
253 | If depth is specified, the result only includes changesets up to | |||
|
254 | the specified generation. | |||
252 | """ |
|
255 | """ | |
253 | args = getargsdict(x, 'ancestors', 'set') |
|
256 | args = getargsdict(x, 'ancestors', 'set depth') | |
254 | if 'set' not in args: |
|
257 | if 'set' not in args: | |
255 | # i18n: "ancestors" is a keyword |
|
258 | # i18n: "ancestors" is a keyword | |
256 | raise error.ParseError(_('ancestors takes at least 1 argument')) |
|
259 | raise error.ParseError(_('ancestors takes at least 1 argument')) | |
257 | return _ancestors(repo, subset, args['set']) |
|
260 | stopdepth = None | |
|
261 | if 'depth' in args: | |||
|
262 | # i18n: "ancestors" is a keyword | |||
|
263 | n = getinteger(args['depth'], _("ancestors expects an integer depth")) | |||
|
264 | if n < 0: | |||
|
265 | raise error.ParseError(_("negative depth")) | |||
|
266 | stopdepth = n + 1 | |||
|
267 | return _ancestors(repo, subset, args['set'], stopdepth=stopdepth) | |||
258 |
|
268 | |||
259 | @predicate('_firstancestors', safe=True) |
|
269 | @predicate('_firstancestors', safe=True) | |
260 | def _firstancestors(repo, subset, x): |
|
270 | def _firstancestors(repo, subset, x): |
@@ -842,6 +842,20 b' ancestor can accept 0 or more arguments' | |||||
842 |
|
842 | |||
843 | test ancestors |
|
843 | test ancestors | |
844 |
|
844 | |||
|
845 | $ hg log -G -T '{rev}\n' --config experimental.graphshorten=True | |||
|
846 | @ 9 | |||
|
847 | o 8 | |||
|
848 | | o 7 | |||
|
849 | | o 6 | |||
|
850 | |/| | |||
|
851 | | o 5 | |||
|
852 | o | 4 | |||
|
853 | | o 3 | |||
|
854 | o | 2 | |||
|
855 | |/ | |||
|
856 | o 1 | |||
|
857 | o 0 | |||
|
858 | ||||
845 | $ log 'ancestors(5)' |
|
859 | $ log 'ancestors(5)' | |
846 | 0 |
|
860 | 0 | |
847 | 1 |
|
861 | 1 | |
@@ -855,6 +869,51 b' test ancestors' | |||||
855 | 2 |
|
869 | 2 | |
856 | 3 |
|
870 | 3 | |
857 |
|
871 | |||
|
872 | test ancestors with depth limit | |||
|
873 | ||||
|
874 | (depth=0 selects the node itself) | |||
|
875 | ||||
|
876 | $ log 'reverse(ancestors(9, depth=0))' | |||
|
877 | 9 | |||
|
878 | ||||
|
879 | (interleaved: '4' would be missing if heap queue were higher depth first) | |||
|
880 | ||||
|
881 | $ log 'reverse(ancestors(8:9, depth=1))' | |||
|
882 | 9 | |||
|
883 | 8 | |||
|
884 | 4 | |||
|
885 | ||||
|
886 | (interleaved: '2' would be missing if heap queue were higher depth first) | |||
|
887 | ||||
|
888 | $ log 'reverse(ancestors(7+8, depth=2))' | |||
|
889 | 8 | |||
|
890 | 7 | |||
|
891 | 6 | |||
|
892 | 5 | |||
|
893 | 4 | |||
|
894 | 2 | |||
|
895 | ||||
|
896 | (walk example above by separate queries) | |||
|
897 | ||||
|
898 | $ log 'reverse(ancestors(8, depth=2)) + reverse(ancestors(7, depth=2))' | |||
|
899 | 8 | |||
|
900 | 4 | |||
|
901 | 2 | |||
|
902 | 7 | |||
|
903 | 6 | |||
|
904 | 5 | |||
|
905 | ||||
|
906 | test bad arguments passed to ancestors() | |||
|
907 | ||||
|
908 | $ log 'ancestors(., depth=-1)' | |||
|
909 | hg: parse error: negative depth | |||
|
910 | [255] | |||
|
911 | $ log 'ancestors(., depth=foo)' | |||
|
912 | hg: parse error: ancestors expects an integer depth | |||
|
913 | [255] | |||
|
914 | ||||
|
915 | test author | |||
|
916 | ||||
858 | $ log 'author(bob)' |
|
917 | $ log 'author(bob)' | |
859 | 2 |
|
918 | 2 | |
860 | $ log 'author("re:bob|test")' |
|
919 | $ log 'author("re:bob|test")' | |
@@ -2996,8 +3055,11 b' optimization to only() works only if anc' | |||||
2996 | ('symbol', '1')) |
|
3055 | ('symbol', '1')) | |
2997 | any) |
|
3056 | any) | |
2998 | define) |
|
3057 | define) | |
2999 | hg: parse error: ancestors takes at most 1 positional arguments |
|
3058 | 0 | |
3000 | [255] |
|
3059 | 1 | |
|
3060 | 3 | |||
|
3061 | 5 | |||
|
3062 | 6 | |||
3001 | $ hg debugrevspec -p optimized 'ancestors(6, 1) - ancestors(4)' |
|
3063 | $ hg debugrevspec -p optimized 'ancestors(6, 1) - ancestors(4)' | |
3002 | * optimized: |
|
3064 | * optimized: | |
3003 | (difference |
|
3065 | (difference | |
@@ -3012,8 +3074,8 b' optimization to only() works only if anc' | |||||
3012 | ('symbol', '4') |
|
3074 | ('symbol', '4') | |
3013 | any) |
|
3075 | any) | |
3014 | define) |
|
3076 | define) | |
3015 | hg: parse error: ancestors takes at most 1 positional arguments |
|
3077 | 5 | |
3016 | [255] |
|
3078 | 6 | |
3017 |
|
3079 | |||
3018 | optimization disabled if keyword arguments passed (because we're too lazy |
|
3080 | optimization disabled if keyword arguments passed (because we're too lazy | |
3019 | to support it) |
|
3081 | to support it) |
General Comments 0
You need to be logged in to leave comments.
Login now