Show More
@@ -279,11 +279,12 b' def _makelogrevset(repo, pats, opts, rev' | |||||
279 | the files to be detailed when displaying the revision. |
|
279 | the files to be detailed when displaying the revision. | |
280 | """ |
|
280 | """ | |
281 | opt2revset = { |
|
281 | opt2revset = { | |
282 | 'follow_first': ('_followfirst()', None), |
|
|||
283 | 'no_merges': ('not merge()', None), |
|
282 | 'no_merges': ('not merge()', None), | |
284 | 'only_merges': ('merge()', None), |
|
283 | 'only_merges': ('merge()', None), | |
285 | '_ancestors': ('ancestors(%(val)s)', None), |
|
284 | '_ancestors': ('ancestors(%(val)s)', None), | |
|
285 | '_fancestors': ('_firstancestors(%(val)s)', None), | |||
286 | '_descendants': ('descendants(%(val)s)', None), |
|
286 | '_descendants': ('descendants(%(val)s)', None), | |
|
287 | '_fdescendants': ('_firstdescendants(%(val)s)', None), | |||
287 | '_matchfiles': ('_matchfiles(%(val)s)', None), |
|
288 | '_matchfiles': ('_matchfiles(%(val)s)', None), | |
288 | 'date': ('date(%(val)r)', None), |
|
289 | 'date': ('date(%(val)r)', None), | |
289 | 'branch': ('branch(%(val)r)', ' or '), |
|
290 | 'branch': ('branch(%(val)r)', ' or '), | |
@@ -299,8 +300,6 b' def _makelogrevset(repo, pats, opts, rev' | |||||
299 | # follow or not follow? |
|
300 | # follow or not follow? | |
300 | follow = opts.get('follow') or opts.get('follow_first') |
|
301 | follow = opts.get('follow') or opts.get('follow_first') | |
301 | followfirst = opts.get('follow_first') |
|
302 | followfirst = opts.get('follow_first') | |
302 | if 'follow_first' in opts: |
|
|||
303 | del opts['follow_first'] |
|
|||
304 | # --follow with FILE behaviour depends on revs... |
|
303 | # --follow with FILE behaviour depends on revs... | |
305 | startrev = revs[0] |
|
304 | startrev = revs[0] | |
306 | followdescendants = len(revs) > 1 and revs[0] < revs[1] |
|
305 | followdescendants = len(revs) > 1 and revs[0] < revs[1] | |
@@ -356,7 +355,10 b' def _makelogrevset(repo, pats, opts, rev' | |||||
356 | if pats: |
|
355 | if pats: | |
357 | opts['_patsfollowfirst'] = list(pats) |
|
356 | opts['_patsfollowfirst'] = list(pats) | |
358 | else: |
|
357 | else: | |
359 |
|
|
358 | if followdescendants: | |
|
359 | opts['_fdescendants'] = str(startrev) | |||
|
360 | else: | |||
|
361 | opts['_fancestors'] = str(startrev) | |||
360 | else: |
|
362 | else: | |
361 | if pats: |
|
363 | if pats: | |
362 | opts['_patsfollow'] = list(pats) |
|
364 | opts['_patsfollow'] = list(pats) |
@@ -13,6 +13,39 b' import match as matchmod' | |||||
13 | from i18n import _ |
|
13 | from i18n import _ | |
14 | import encoding |
|
14 | import encoding | |
15 |
|
15 | |||
|
16 | def _revancestors(repo, revs, followfirst): | |||
|
17 | """Like revlog.ancestors(), but supports followfirst.""" | |||
|
18 | cut = followfirst and 1 or None | |||
|
19 | cl = repo.changelog | |||
|
20 | visit = list(revs) | |||
|
21 | seen = set([nodemod.nullrev]) | |||
|
22 | while visit: | |||
|
23 | for parent in cl.parentrevs(visit.pop(0))[:cut]: | |||
|
24 | if parent not in seen: | |||
|
25 | visit.append(parent) | |||
|
26 | seen.add(parent) | |||
|
27 | yield parent | |||
|
28 | ||||
|
29 | def _revdescendants(repo, revs, followfirst): | |||
|
30 | """Like revlog.descendants() but supports followfirst.""" | |||
|
31 | cut = followfirst and 1 or None | |||
|
32 | cl = repo.changelog | |||
|
33 | first = min(revs) | |||
|
34 | if first == nodemod.nullrev: | |||
|
35 | # Are there nodes with a null first parent and a non-null | |||
|
36 | # second one? Maybe. Do we care? Probably not. | |||
|
37 | for i in cl: | |||
|
38 | yield i | |||
|
39 | return | |||
|
40 | ||||
|
41 | seen = set(revs) | |||
|
42 | for i in xrange(first + 1, len(cl)): | |||
|
43 | for x in cl.parentrevs(i)[:cut]: | |||
|
44 | if x != nodemod.nullrev and x in seen: | |||
|
45 | seen.add(i) | |||
|
46 | yield i | |||
|
47 | break | |||
|
48 | ||||
16 | elements = { |
|
49 | elements = { | |
17 | "(": (20, ("group", 1, ")"), ("func", 1, ")")), |
|
50 | "(": (20, ("group", 1, ")"), ("func", 1, ")")), | |
18 | "~": (18, None, ("ancestor", 18)), |
|
51 | "~": (18, None, ("ancestor", 18)), | |
@@ -203,15 +236,23 b' def ancestor(repo, subset, x):' | |||||
203 |
|
236 | |||
204 | return [r for r in an if r in subset] |
|
237 | return [r for r in an if r in subset] | |
205 |
|
238 | |||
|
239 | def _ancestors(repo, subset, x, followfirst=False): | |||
|
240 | args = getset(repo, range(len(repo)), x) | |||
|
241 | if not args: | |||
|
242 | return [] | |||
|
243 | s = set(_revancestors(repo, args, followfirst)) | set(args) | |||
|
244 | return [r for r in subset if r in s] | |||
|
245 | ||||
206 | def ancestors(repo, subset, x): |
|
246 | def ancestors(repo, subset, x): | |
207 | """``ancestors(set)`` |
|
247 | """``ancestors(set)`` | |
208 | Changesets that are ancestors of a changeset in set. |
|
248 | Changesets that are ancestors of a changeset in set. | |
209 | """ |
|
249 | """ | |
210 | args = getset(repo, range(len(repo)), x) |
|
250 | return _ancestors(repo, subset, x) | |
211 | if not args: |
|
251 | ||
212 | return [] |
|
252 | def _firstancestors(repo, subset, x): | |
213 | s = set(repo.changelog.ancestors(*args)) | set(args) |
|
253 | # ``_firstancestors(set)`` | |
214 | return [r for r in subset if r in s] |
|
254 | # Like ``ancestors(set)`` but follows only the first parents. | |
|
255 | return _ancestors(repo, subset, x, followfirst=True) | |||
215 |
|
256 | |||
216 | def ancestorspec(repo, subset, x, n): |
|
257 | def ancestorspec(repo, subset, x, n): | |
217 | """``set~n`` |
|
258 | """``set~n`` | |
@@ -395,15 +436,23 b' def desc(repo, subset, x):' | |||||
395 | l.append(r) |
|
436 | l.append(r) | |
396 | return l |
|
437 | return l | |
397 |
|
438 | |||
|
439 | def _descendants(repo, subset, x, followfirst=False): | |||
|
440 | args = getset(repo, range(len(repo)), x) | |||
|
441 | if not args: | |||
|
442 | return [] | |||
|
443 | s = set(_revdescendants(repo, args, followfirst)) | set(args) | |||
|
444 | return [r for r in subset if r in s] | |||
|
445 | ||||
398 | def descendants(repo, subset, x): |
|
446 | def descendants(repo, subset, x): | |
399 | """``descendants(set)`` |
|
447 | """``descendants(set)`` | |
400 | Changesets which are descendants of changesets in set. |
|
448 | Changesets which are descendants of changesets in set. | |
401 | """ |
|
449 | """ | |
402 | args = getset(repo, range(len(repo)), x) |
|
450 | return _descendants(repo, subset, x) | |
403 | if not args: |
|
451 | ||
404 | return [] |
|
452 | def _firstdescendants(repo, subset, x): | |
405 | s = set(repo.changelog.descendants(*args)) | set(args) |
|
453 | # ``_firstdescendants(set)`` | |
406 | return [r for r in subset if r in s] |
|
454 | # Like ``descendants(set)`` but follows only the first parents. | |
|
455 | return _descendants(repo, subset, x, followfirst=True) | |||
407 |
|
456 | |||
408 | def draft(repo, subset, x): |
|
457 | def draft(repo, subset, x): | |
409 | """``draft()`` |
|
458 | """``draft()`` | |
@@ -454,16 +503,7 b' def _follow(repo, subset, x, name, follo' | |||||
454 | else: |
|
503 | else: | |
455 | return [] |
|
504 | return [] | |
456 | else: |
|
505 | else: | |
457 | cut = followfirst and 1 or None |
|
506 | s = set(_revancestors(repo, [c.rev()], followfirst)) | set([c.rev()]) | |
458 | cl = repo.changelog |
|
|||
459 | s = set() |
|
|||
460 | visit = [c.rev()] |
|
|||
461 | while visit: |
|
|||
462 | for prev in cl.parentrevs(visit.pop(0))[:cut]: |
|
|||
463 | if prev not in s and prev != nodemod.nullrev: |
|
|||
464 | visit.append(prev) |
|
|||
465 | s.add(prev) |
|
|||
466 | s.add(c.rev()) |
|
|||
467 |
|
507 | |||
468 | return [r for r in subset if r in s] |
|
508 | return [r for r in subset if r in s] | |
469 |
|
509 | |||
@@ -1055,6 +1095,7 b' symbols = {' | |||||
1055 | "all": getall, |
|
1095 | "all": getall, | |
1056 | "ancestor": ancestor, |
|
1096 | "ancestor": ancestor, | |
1057 | "ancestors": ancestors, |
|
1097 | "ancestors": ancestors, | |
|
1098 | "_firstancestors": _firstancestors, | |||
1058 | "author": author, |
|
1099 | "author": author, | |
1059 | "bisect": bisect, |
|
1100 | "bisect": bisect, | |
1060 | "bisected": bisected, |
|
1101 | "bisected": bisected, | |
@@ -1066,6 +1107,7 b' symbols = {' | |||||
1066 | "date": date, |
|
1107 | "date": date, | |
1067 | "desc": desc, |
|
1108 | "desc": desc, | |
1068 | "descendants": descendants, |
|
1109 | "descendants": descendants, | |
|
1110 | "_firstdescendants": _firstdescendants, | |||
1069 | "draft": draft, |
|
1111 | "draft": draft, | |
1070 | "file": hasfile, |
|
1112 | "file": hasfile, | |
1071 | "filelog": filelog, |
|
1113 | "filelog": filelog, |
@@ -1746,8 +1746,8 b' Test --follow-first' | |||||
1746 | [] |
|
1746 | [] | |
1747 | (group |
|
1747 | (group | |
1748 | (func |
|
1748 | (func | |
1749 |
('symbol', '_f |
|
1749 | ('symbol', '_firstancestors') | |
1750 | None)) |
|
1750 | ('symbol', '6'))) | |
1751 |
|
1751 | |||
1752 | Cannot compare with log --follow-first FILE as it never worked |
|
1752 | Cannot compare with log --follow-first FILE as it never worked | |
1753 |
|
1753 | |||
@@ -1967,6 +1967,23 b' Test --follow and forward --rev' | |||||
1967 | +nodetag 6 |
|
1967 | +nodetag 6 | |
1968 | [1] |
|
1968 | [1] | |
1969 |
|
1969 | |||
|
1970 | Test --follow-first and forward --rev | |||
|
1971 | ||||
|
1972 | $ testlog --follow-first -r6 -r8 -r5 -r7 -r4 | |||
|
1973 | ['6', '8', '5', '7', '4'] | |||
|
1974 | (group | |||
|
1975 | (func | |||
|
1976 | ('symbol', '_firstdescendants') | |||
|
1977 | ('symbol', '6'))) | |||
|
1978 | --- log.nodes * (glob) | |||
|
1979 | +++ glog.nodes * (glob) | |||
|
1980 | @@ -1,3 +1,3 @@ | |||
|
1981 | -nodetag 6 | |||
|
1982 | nodetag 8 | |||
|
1983 | nodetag 7 | |||
|
1984 | +nodetag 6 | |||
|
1985 | [1] | |||
|
1986 | ||||
1970 | Test --follow and backward --rev |
|
1987 | Test --follow and backward --rev | |
1971 |
|
1988 | |||
1972 | $ testlog --follow -r6 -r5 -r7 -r8 -r4 |
|
1989 | $ testlog --follow -r6 -r5 -r7 -r8 -r4 | |
@@ -1976,3 +1993,11 b' Test --follow and backward --rev' | |||||
1976 | ('symbol', 'ancestors') |
|
1993 | ('symbol', 'ancestors') | |
1977 | ('symbol', '6'))) |
|
1994 | ('symbol', '6'))) | |
1978 |
|
1995 | |||
|
1996 | Test --follow-first and backward --rev | |||
|
1997 | ||||
|
1998 | $ testlog --follow-first -r6 -r5 -r7 -r8 -r4 | |||
|
1999 | ['6', '5', '7', '8', '4'] | |||
|
2000 | (group | |||
|
2001 | (func | |||
|
2002 | ('symbol', '_firstancestors') | |||
|
2003 | ('symbol', '6'))) |
General Comments 0
You need to be logged in to leave comments.
Login now