##// END OF EJS Templates
graphlog: implement --follow-first...
Patrick Mezard -
r16174:0a73c4bd default
parent child Browse files
Show More
@@ -237,7 +237,7 b' def get_revs(repo, rev_opt):'
237 return (len(repo) - 1, 0)
237 return (len(repo) - 1, 0)
238
238
239 def check_unsupported_flags(pats, opts):
239 def check_unsupported_flags(pats, opts):
240 for op in ["follow_first", "copies", "newest_first"]:
240 for op in ["copies", "newest_first"]:
241 if op in opts and opts[op]:
241 if op in opts and opts[op]:
242 raise util.Abort(_("-G/--graph option is incompatible with --%s")
242 raise util.Abort(_("-G/--graph option is incompatible with --%s")
243 % op.replace("_", "-"))
243 % op.replace("_", "-"))
@@ -246,18 +246,20 b' def revset(repo, pats, opts):'
246 """Return revset str built of revisions, log options and file patterns.
246 """Return revset str built of revisions, log options and file patterns.
247 """
247 """
248 opt2revset = {
248 opt2revset = {
249 'follow': ('follow()', None),
249 'follow': ('follow()', None),
250 'no_merges': ('not merge()', None),
250 'follow_first': ('_followfirst()', None),
251 'only_merges': ('merge()', None),
251 'no_merges': ('not merge()', None),
252 'removed': ('removes("*")', None),
252 'only_merges': ('merge()', None),
253 'date': ('date(%(val)r)', None),
253 'removed': ('removes("*")', None),
254 'branch': ('branch(%(val)r)', ' or '),
254 'date': ('date(%(val)r)', None),
255 '_patslog': ('filelog(%(val)r)', ' or '),
255 'branch': ('branch(%(val)r)', ' or '),
256 '_patsfollow': ('follow(%(val)r)', ' or '),
256 '_patslog': ('filelog(%(val)r)', ' or '),
257 'keyword': ('keyword(%(val)r)', ' or '),
257 '_patsfollow': ('follow(%(val)r)', ' or '),
258 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
258 '_patsfollowfirst': ('_followfirst(%(val)r)', ' or '),
259 'user': ('user(%(val)r)', ' or '),
259 'keyword': ('keyword(%(val)r)', ' or '),
260 'rev': ('%(val)s', ' or '),
260 'prune': ('not (%(val)r or ancestors(%(val)r))', ' and '),
261 'user': ('user(%(val)r)', ' or '),
262 'rev': ('%(val)s', ' or '),
261 }
263 }
262
264
263 opts = dict(opts)
265 opts = dict(opts)
@@ -266,9 +268,12 b' def revset(repo, pats, opts):'
266 if 'branch' in opts and 'only_branch' in opts:
268 if 'branch' in opts and 'only_branch' in opts:
267 opts['branch'] = opts['branch'] + opts.pop('only_branch')
269 opts['branch'] = opts['branch'] + opts.pop('only_branch')
268
270
269 follow = opts.get('follow')
271 follow = opts.get('follow') or opts.get('follow_first')
272 followfirst = opts.get('follow_first')
270 if 'follow' in opts:
273 if 'follow' in opts:
271 del opts['follow']
274 del opts['follow']
275 if 'follow_first' in opts:
276 del opts['follow_first']
272 # pats/include/exclude are passed to match.match() directly in
277 # pats/include/exclude are passed to match.match() directly in
273 # _matchfile() revset but walkchangerevs() builds its matcher with
278 # _matchfile() revset but walkchangerevs() builds its matcher with
274 # scmutil.match(). The difference is input pats are globbed on
279 # scmutil.match(). The difference is input pats are globbed on
@@ -310,10 +315,16 b' def revset(repo, pats, opts):'
310 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
315 opts['rev'] = opts.get('rev', []) + ['_matchfiles(%s)' % matchargs]
311 else:
316 else:
312 if follow:
317 if follow:
313 if pats:
318 if followfirst:
314 opts['_patsfollow'] = list(pats)
319 if pats:
320 opts['_patsfollowfirst'] = list(pats)
321 else:
322 opts['follow_first'] = True
315 else:
323 else:
316 opts['follow'] = True
324 if pats:
325 opts['_patsfollow'] = list(pats)
326 else:
327 opts['follow'] = True
317 else:
328 else:
318 opts['_patslog'] = list(pats)
329 opts['_patslog'] = list(pats)
319
330
@@ -465,6 +465,40 b' def follow(repo, subset, x):'
465
465
466 return [r for r in subset if r in s]
466 return [r for r in subset if r in s]
467
467
468 def _followfirst(repo, subset, x):
469 # ``followfirst([file])``
470 # Like ``follow([file])`` but follows only the first parent of
471 # every revision or file revision.
472 # i18n: "_followfirst" is a keyword
473 l = getargs(x, 0, 1, _("_followfirst takes no arguments or a filename"))
474 c = repo['.']
475 if l:
476 x = getstring(l[0], _("_followfirst expected a filename"))
477 if x not in c:
478 return []
479 cx = c[x]
480 visit = {}
481 s = set([cx.linkrev()])
482 while True:
483 for p in cx.parents()[:1]:
484 visit[(p.rev(), p.node())] = p
485 if not visit:
486 break
487 cx = visit.pop(max(visit))
488 s.add(cx.rev())
489 else:
490 cl = repo.changelog
491 s = set()
492 visit = [c.rev()]
493 while visit:
494 for prev in cl.parentrevs(visit.pop(0))[:1]:
495 if prev not in s and prev != nodemod.nullrev:
496 visit.append(prev)
497 s.add(prev)
498 s.add(c.rev())
499
500 return [r for r in subset if r in s]
501
468 def getall(repo, subset, x):
502 def getall(repo, subset, x):
469 """``all()``
503 """``all()``
470 All changesets, the same as ``0:tip``.
504 All changesets, the same as ``0:tip``.
@@ -965,6 +999,7 b' symbols = {'
965 "filelog": filelog,
999 "filelog": filelog,
966 "first": first,
1000 "first": first,
967 "follow": follow,
1001 "follow": follow,
1002 "_followfirst": _followfirst,
968 "grep": grep,
1003 "grep": grep,
969 "head": head,
1004 "head": head,
970 "heads": heads,
1005 "heads": heads,
@@ -1618,3 +1618,27 b' Test --follow and multiple files'
1618 nodetag 1
1618 nodetag 1
1619 nodetag 0
1619 nodetag 0
1620
1620
1621 Test --follow-first
1622
1623 $ hg up -q 3
1624 $ echo ee > e
1625 $ hg ci -Am "add another e" e
1626 created new head
1627 $ hg merge --tool internal:other 4
1628 0 files updated, 1 files merged, 1 files removed, 0 files unresolved
1629 (branch merge, don't forget to commit)
1630 $ echo merge > e
1631 $ hg ci -m "merge 5 and 4"
1632 $ testlog --follow-first
1633 ('group', ('func', ('symbol', '_followfirst'), None))
1634
1635 Cannot compare with log --follow-first FILE as it never worked
1636
1637 $ hg log -G --print-revset --follow-first e
1638 ('group', ('group', ('func', ('symbol', '_followfirst'), ('string', 'e'))))
1639 $ hg log -G --follow-first e --template '{rev} {desc|firstline}\n'
1640 @ 6 merge 5 and 4
1641 |\
1642 o | 5 add another e
1643 | |
1644
General Comments 0
You need to be logged in to leave comments. Login now