diff --git a/mercurial/commands.py b/mercurial/commands.py --- a/mercurial/commands.py +++ b/mercurial/commands.py @@ -371,6 +371,13 @@ def addremove(ui, repo, *pats, **opts): _(b'revset to not display (EXPERIMENTAL)'), _(b'REV'), ), + ( + b'L', + b'line-range', + [], + _(b'follow line range of specified file (EXPERIMENTAL)'), + _(b'FILE,RANGE'), + ), ] + diffwsopts + walkopts @@ -399,6 +406,13 @@ def annotate(ui, repo, *pats, **opts): .. container:: verbose + Use -L/--line-range FILE,M:N options to filter the output to the lines + from M to N in FILE. This option is incompatible with --no-follow and + cannot be combined with file pattern arguments. When combined with --rev + the line ranges refer to the state of the file at the requested revision. + + .. container:: verbose + Template: The following keywords are supported in addition to the common template @@ -419,7 +433,20 @@ def annotate(ui, repo, *pats, **opts): Returns 0 on success. """ opts = pycompat.byteskwargs(opts) - if not pats: + + linerange = opts.get(b'line_range') + + if linerange and opts.get(b'no_follow'): + raise error.InputError( + _(b'--line-range is incompatible with --no-follow') + ) + + if pats and linerange: + raise error.InputError( + _(b'cannot combine filename or pattern and --line-range') + ) + + if not pats and not linerange: raise error.InputError( _(b'at least one filename or pattern is required') ) @@ -450,6 +477,12 @@ def annotate(ui, repo, *pats, **opts): repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn') ctx = logcmdutil.revsingle(repo, rev) + if not pats: + pats = [ + fname + for fname, _ranges in logcmdutil._parselinerangeopt(repo, opts) + ] + ui.pager(b'annotate') rootfm = ui.formatter(b'annotate', opts) if ui.debugflag: @@ -554,6 +587,16 @@ def annotate(ui, repo, *pats, **opts): lines = fctx.annotate( follow=follow, skiprevs=skiprevs, diffopts=diffopts ) + if linerange: + _fname, (line_start, line_end) = list( + logcmdutil._parselinerangeopt(repo, opts) + )[0] + lines = [ + line + for no, line in enumerate(lines) + if line_start <= no < line_end + ] + if not lines: fm.end() continue @@ -1359,7 +1402,6 @@ def branch(ui, repo, label=None, **opts) repo.dirstate.setbranch(label, repo.currenttransaction()) ui.status(_(b'reset working directory to branch %s\n') % label) elif label: - scmutil.checknewlabel(repo, label, b'branch') if revs: return cmdutil.changebranch(ui, repo, revs, label, **opts) diff --git a/tests/test-annotate.t b/tests/test-annotate.t --- a/tests/test-annotate.t +++ b/tests/test-annotate.t @@ -430,6 +430,69 @@ linkrev vs rev with -l 1:2: a 1:3: a +annotate line-range + + $ hg annotate -l -L b,8:10 + 8: 8: more + 9: 9: more + 10:10: more + +annotate line-range beyond last line + + $ hg annotate -l -L b,8:13 + 8: 8: more + 9: 9: more + 10:10: more + +annotate line-range before first line + + $ hg annotate -l -L b,0:2 + hg: parse error: fromline must be strictly positive + [10] + +annotate line-range with --rev + $ hg annotate -l -L b,5:7 + 4:5: c + 3:5: b5 + 7:7: d + $ sed 's/d/x/' b > b.new + $ mv b.new b + $ hg annotate --rev 'wdir()' -l -L b,5:7 + 4 :5: c + 3 :5: b5 + 10+:7: x + $ hg annotate -l -L b,5:7 + 4:5: c + 3:5: b5 + 7:7: d + $ hg revert --no-backup b + $ hg annotate --rev 3 -l b + 0:1: a + 1:2: a + 1:3: a + 3:4: b4 + 3:5: b5 + 3:6: b6 + $ hg annotate --rev 3 -l -L b,5:7 + 3:5: b5 + 3:6: b6 + +annotate line-range invalid combination of options + + $ hg annotate --no-follow -L b,5:7 + abort: --line-range is incompatible with --no-follow + [10] + $ hg annotate -L b,5:7 a + abort: cannot combine filename or pattern and --line-range + [10] + +annote line-range with glob patterns + + $ hg annotate -l -L glob:b*,5:7 + 4:5: c + 3:5: b5 + 7:7: d + Issue589: "undelete" sequence leads to crash annotate was crashing when trying to --follow something diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -260,7 +260,7 @@ Show all commands + options add: include, exclude, subrepos, dry-run addremove: similarity, subrepos, include, exclude, dry-run admin::verify: check, option - annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template + annotate: rev, follow, no-follow, text, user, file, date, number, changeset, line-number, skip, line-range, ignore-all-space, ignore-space-change, ignore-blank-lines, ignore-space-at-eol, include, exclude, template archive: no-decode, prefix, rev, type, subrepos, include, exclude backout: merge, commit, no-commit, parent, rev, edit, tool, include, exclude, message, logfile, date, user bisect: reset, good, bad, skip, extend, command, noupdate