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