##// END OF EJS Templates
revset: add a followlines(file, fromline, toline[, rev]) revset...
Denis Laxalde -
r30719:42c75b4f default
parent child Browse files
Show More
@@ -1068,6 +1068,52 b' def _followfirst(repo, subset, x):'
1068 1068 # of every revisions or files revisions.
1069 1069 return _follow(repo, subset, x, '_followfirst', followfirst=True)
1070 1070
1071 @predicate('followlines(file, fromline, toline[, rev=.])', safe=True)
1072 def followlines(repo, subset, x):
1073 """Changesets modifying `file` in line range ('fromline', 'toline').
1074
1075 Line range corresponds to 'file' content at 'rev' and should hence be
1076 consistent with file size. If rev is not specified, working directory's
1077 parent is used.
1078 """
1079 from . import context # avoid circular import issues
1080
1081 args = getargs(x, 3, 4, _("followlines takes at least three arguments"))
1082
1083 rev = '.'
1084 if len(args) == 4:
1085 revarg = getargsdict(args[3], 'followlines', 'rev')
1086 if 'rev' in revarg:
1087 revs = getset(repo, fullreposet(repo), revarg['rev'])
1088 if len(revs) != 1:
1089 raise error.ParseError(
1090 _("followlines expects exactly one revision"))
1091 rev = revs.last()
1092
1093 pat = getstring(args[0], _("followlines requires a pattern"))
1094 if not matchmod.patkind(pat):
1095 fname = pathutil.canonpath(repo.root, repo.getcwd(), pat)
1096 else:
1097 m = matchmod.match(repo.root, repo.getcwd(), [pat], ctx=repo[rev])
1098 files = [f for f in repo[rev] if m(f)]
1099 if len(files) != 1:
1100 raise error.ParseError(_("followlines expects exactly one file"))
1101 fname = files[0]
1102
1103 try:
1104 fromline, toline = [int(getsymbol(a)) for a in args[1:3]]
1105 except ValueError:
1106 raise error.ParseError(_("line range bounds must be integers"))
1107 if toline - fromline < 0:
1108 raise error.ParseError(_("line range must be positive"))
1109 if fromline < 1:
1110 raise error.ParseError(_("fromline must be strictly positive"))
1111 fromline -= 1
1112
1113 fctx = repo[rev].filectx(fname)
1114 revs = (c.rev() for c in context.blockancestors(fctx, fromline, toline))
1115 return subset & generatorset(revs, iterasc=False)
1116
1071 1117 @predicate('all()', safe=True)
1072 1118 def getall(repo, subset, x):
1073 1119 """All changesets, the same as ``0:tip``.
@@ -480,6 +480,127 b' annotate removed file'
480 480 [255]
481 481 #endif
482 482
483 $ hg revert --all --no-backup --quiet
484 $ hg id -n
485 20
486
487 Test followlines() revset
488
489 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5)'
490 16: baz:0
491 19: baz:3
492 20: baz:4
493 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5, rev=20)'
494 16: baz:0
495 19: baz:3
496 20: baz:4
497 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5, rev=.^)'
498 16: baz:0
499 19: baz:3
500 $ printf "0\n0\n" | cat - baz > baz1
501 $ mv baz1 baz
502 $ hg ci -m 'added two lines with 0'
503 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
504 16: baz:0
505 19: baz:3
506 20: baz:4
507 $ echo 6 >> baz
508 $ hg ci -m 'added line 8'
509 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
510 16: baz:0
511 19: baz:3
512 20: baz:4
513 $ sed 's/3/3+/' baz > baz.new
514 $ mv baz.new baz
515 $ hg ci -m 'baz:3->3+'
516 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
517 16: baz:0
518 19: baz:3
519 20: baz:4
520 23: baz:3->3+
521 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1, 2)'
522 21: added two lines with 0
523
524 file patterns are okay
525 $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1, 2)'
526 21: added two lines with 0
527
528 renames are followed
529 $ hg mv baz qux
530 $ sed 's/4/4+/' qux > qux.new
531 $ mv qux.new qux
532 $ hg ci -m 'qux:4->4+'
533 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)'
534 16: baz:0
535 19: baz:3
536 20: baz:4
537 23: baz:3->3+
538 24: qux:4->4+
539 $ hg up 23 --quiet
540
541 merge
542 $ echo 7 >> baz
543 $ hg ci -m 'one more line, out of line range'
544 created new head
545 $ sed 's/3+/3-/' baz > baz.new
546 $ mv baz.new baz
547 $ hg ci -m 'baz:3+->3-'
548 $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)'
549 16: baz:0
550 19: baz:3
551 20: baz:4
552 23: baz:3->3+
553 26: baz:3+->3-
554 $ hg merge 24
555 merging baz and qux to qux
556 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
557 (branch merge, don't forget to commit)
558 $ hg ci -m merge
559 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)'
560 16: baz:0
561 19: baz:3
562 20: baz:4
563 23: baz:3->3+
564 24: qux:4->4+
565 26: baz:3+->3-
566 27: merge
567 $ hg up 24 --quiet
568 $ hg merge 26
569 merging qux and baz to qux
570 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
571 (branch merge, don't forget to commit)
572 $ hg ci -m 'merge from other side'
573 created new head
574 $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)'
575 16: baz:0
576 19: baz:3
577 20: baz:4
578 23: baz:3->3+
579 24: qux:4->4+
580 26: baz:3+->3-
581 28: merge from other side
582 $ hg up 23 --quiet
583
584 check error cases
585 $ hg log -r 'followlines(baz, 1, 2, rev=desc("b"))'
586 hg: parse error: followlines expects exactly one revision
587 [255]
588 $ hg log -r 'followlines("glob:*", 1, 2)'
589 hg: parse error: followlines expects exactly one file
590 [255]
591 $ hg log -r 'followlines(baz, x, 4)'
592 hg: parse error: line range bounds must be integers
593 [255]
594 $ hg log -r 'followlines(baz, 5, 4)'
595 hg: parse error: line range must be positive
596 [255]
597 $ hg log -r 'followlines(baz, 0, 4)'
598 hg: parse error: fromline must be strictly positive
599 [255]
600 $ hg log -r 'followlines(baz, 2, 40)'
601 abort: line range exceeds file size
602 [255]
603
483 604 Test annotate with whitespace options
484 605
485 606 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now