Show More
@@ -1068,6 +1068,52 b' def _followfirst(repo, subset, x):' | |||||
1068 | # of every revisions or files revisions. |
|
1068 | # of every revisions or files revisions. | |
1069 | return _follow(repo, subset, x, '_followfirst', followfirst=True) |
|
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 | @predicate('all()', safe=True) |
|
1117 | @predicate('all()', safe=True) | |
1072 | def getall(repo, subset, x): |
|
1118 | def getall(repo, subset, x): | |
1073 | """All changesets, the same as ``0:tip``. |
|
1119 | """All changesets, the same as ``0:tip``. |
@@ -480,6 +480,127 b' annotate removed file' | |||||
480 | [255] |
|
480 | [255] | |
481 | #endif |
|
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 | Test annotate with whitespace options |
|
604 | Test annotate with whitespace options | |
484 |
|
605 | |||
485 | $ cd .. |
|
606 | $ cd .. |
General Comments 0
You need to be logged in to leave comments.
Login now