diff --git a/mercurial/revset.py b/mercurial/revset.py index 392b9199bf..e7743773c4 100644 --- a/mercurial/revset.py +++ b/mercurial/revset.py @@ -329,6 +329,20 @@ def getlist(x): return list(x[1:]) return [x] +def getrange(x, err): + if not x: + raise error.ParseError(err) + op = x[0] + if op == 'range': + return x[1], x[2] + elif op == 'rangepre': + return None, x[1] + elif op == 'rangepost': + return x[1], None + elif op == 'rangeall': + return None, None + raise error.ParseError(err) + def getargs(x, min, max, err): l = getlist(x) if len(l) < min or (max >= 0 and len(l) > max): @@ -1083,7 +1097,7 @@ def _followfirst(repo, subset, x): # of every revisions or files revisions. return _follow(repo, subset, x, '_followfirst', followfirst=True) -@predicate('followlines(file, fromline, toline[, startrev=.])', safe=True) +@predicate('followlines(file, fromline:toline[, startrev=.])', safe=True) def followlines(repo, subset, x): """Changesets modifying `file` in line range ('fromline', 'toline'). @@ -1094,8 +1108,8 @@ def followlines(repo, subset, x): from . import context # avoid circular import issues args = getargsdict(x, 'followlines', 'file *lines startrev') - if len(args['lines']) != 2: - raise error.ParseError(_("followlines takes at least three arguments")) + if len(args['lines']) != 1: + raise error.ParseError(_("followlines requires a line range")) rev = '.' if 'startrev' in args: @@ -1115,8 +1129,9 @@ def followlines(repo, subset, x): raise error.ParseError(_("followlines expects exactly one file")) fname = files[0] + lr = getrange(args['lines'][0], _("followlines expects a line range")) fromline, toline = [getinteger(a, _("line range bounds must be integers")) - for a in args['lines']] + for a in lr] if toline - fromline < 0: raise error.ParseError(_("line range must be positive")) if fromline < 1: diff --git a/tests/test-annotate.t b/tests/test-annotate.t index a399ce65c9..e103f93fa0 100644 --- a/tests/test-annotate.t +++ b/tests/test-annotate.t @@ -486,43 +486,43 @@ annotate removed file Test followlines() revset - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5)' 16: baz:0 19: baz:3 20: baz:4 - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5, startrev=20)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=20)' 16: baz:0 19: baz:3 20: baz:4 - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3, 5, startrev=.^)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 3:5, startrev=.^)' 16: baz:0 19: baz:3 $ printf "0\n0\n" | cat - baz > baz1 $ mv baz1 baz $ hg ci -m 'added two lines with 0' - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)' 16: baz:0 19: baz:3 20: baz:4 $ echo 6 >> baz $ hg ci -m 'added line 8' - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)' 16: baz:0 19: baz:3 20: baz:4 $ sed 's/3/3+/' baz > baz.new $ mv baz.new baz $ hg ci -m 'baz:3->3+' - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)' 16: baz:0 19: baz:3 20: baz:4 23: baz:3->3+ - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1, 2)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 1:2)' 21: added two lines with 0 file patterns are okay - $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1, 2)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines("path:baz", 1:2)' 21: added two lines with 0 renames are followed @@ -530,7 +530,7 @@ renames are followed $ sed 's/4/4+/' qux > qux.new $ mv qux.new qux $ hg ci -m 'qux:4->4+' - $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)' 16: baz:0 19: baz:3 20: baz:4 @@ -545,7 +545,7 @@ merge $ sed 's/3+/3-/' baz > baz.new $ mv baz.new baz $ hg ci -m 'baz:3+->3-' - $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(baz, 5:7)' 16: baz:0 19: baz:3 20: baz:4 @@ -556,7 +556,7 @@ merge 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m merge - $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)' 16: baz:0 19: baz:3 20: baz:4 @@ -571,7 +571,7 @@ merge (branch merge, don't forget to commit) $ hg ci -m 'merge from other side' created new head - $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5, 7)' + $ hg log -T '{rev}: {desc}\n' -r 'followlines(qux, 5:7)' 16: baz:0 19: baz:3 20: baz:4 @@ -586,27 +586,33 @@ check error cases hg: parse error: followlines takes at least 1 positional arguments [255] $ hg log -r 'followlines(baz)' - hg: parse error: followlines takes at least three arguments + hg: parse error: followlines requires a line range [255] $ hg log -r 'followlines(baz, 1)' - hg: parse error: followlines takes at least three arguments + hg: parse error: followlines expects a line range [255] - $ hg log -r 'followlines(baz, 1, 2, startrev=desc("b"))' + $ hg log -r 'followlines(baz, 1:2, startrev=desc("b"))' hg: parse error: followlines expects exactly one revision [255] - $ hg log -r 'followlines("glob:*", 1, 2)' + $ hg log -r 'followlines("glob:*", 1:2)' hg: parse error: followlines expects exactly one file [255] - $ hg log -r 'followlines(baz, x, 4)' + $ hg log -r 'followlines(baz, 1:)' hg: parse error: line range bounds must be integers [255] - $ hg log -r 'followlines(baz, 5, 4)' + $ hg log -r 'followlines(baz, :1)' + hg: parse error: line range bounds must be integers + [255] + $ hg log -r 'followlines(baz, x:4)' + hg: parse error: line range bounds must be integers + [255] + $ hg log -r 'followlines(baz, 5:4)' hg: parse error: line range must be positive [255] - $ hg log -r 'followlines(baz, 0, 4)' + $ hg log -r 'followlines(baz, 0:4)' hg: parse error: fromline must be strictly positive [255] - $ hg log -r 'followlines(baz, 2, 40)' + $ hg log -r 'followlines(baz, 2:40)' abort: line range exceeds file size [255]