comparison mercurial/commands.py @ 51395:e9304c39e075

annotate: limit output to range of lines
author Zeger Van de Vannet <zeger@vandevan.net>
date Wed, 14 Feb 2024 08:14:46 +0100
parents 508fd40dc86a
children e2dfa403452d
comparison
equal deleted inserted replaced
51394:b01e7d97e167 51395:e9304c39e075
369 b'skip', 369 b'skip',
370 [], 370 [],
371 _(b'revset to not display (EXPERIMENTAL)'), 371 _(b'revset to not display (EXPERIMENTAL)'),
372 _(b'REV'), 372 _(b'REV'),
373 ), 373 ),
374 (
375 b'L',
376 b'line-range',
377 [],
378 _(b'follow line range of specified file (EXPERIMENTAL)'),
379 _(b'FILE,RANGE'),
380 ),
374 ] 381 ]
375 + diffwsopts 382 + diffwsopts
376 + walkopts 383 + walkopts
377 + formatteropts, 384 + formatteropts,
378 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'), 385 _(b'[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
397 anyway, although the results will probably be neither useful 404 anyway, although the results will probably be neither useful
398 nor desirable. 405 nor desirable.
399 406
400 .. container:: verbose 407 .. container:: verbose
401 408
409 Use -L/--line-range FILE,M:N options to filter the output to the lines
410 from M to N in FILE. This option is incompatible with --no-follow and
411 cannot be combined with file pattern arguments. When combined with --rev
412 the line ranges refer to the state of the file at the requested revision.
413
414 .. container:: verbose
415
402 Template: 416 Template:
403 417
404 The following keywords are supported in addition to the common template 418 The following keywords are supported in addition to the common template
405 keywords and functions. See also :hg:`help templates`. 419 keywords and functions. See also :hg:`help templates`.
406 420
417 See :hg:`help templates.operators` for the list expansion syntax. 431 See :hg:`help templates.operators` for the list expansion syntax.
418 432
419 Returns 0 on success. 433 Returns 0 on success.
420 """ 434 """
421 opts = pycompat.byteskwargs(opts) 435 opts = pycompat.byteskwargs(opts)
422 if not pats: 436
437 linerange = opts.get(b'line_range')
438
439 if linerange and opts.get(b'no_follow'):
440 raise error.InputError(
441 _(b'--line-range is incompatible with --no-follow')
442 )
443
444 if pats and linerange:
445 raise error.InputError(
446 _(b'cannot combine filename or pattern and --line-range')
447 )
448
449 if not pats and not linerange:
423 raise error.InputError( 450 raise error.InputError(
424 _(b'at least one filename or pattern is required') 451 _(b'at least one filename or pattern is required')
425 ) 452 )
426 453
427 if opts.get(b'follow'): 454 if opts.get(b'follow'):
447 474
448 rev = opts.get(b'rev') 475 rev = opts.get(b'rev')
449 if rev: 476 if rev:
450 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn') 477 repo = scmutil.unhidehashlikerevs(repo, [rev], b'nowarn')
451 ctx = logcmdutil.revsingle(repo, rev) 478 ctx = logcmdutil.revsingle(repo, rev)
479
480 if not pats:
481 pats = [
482 fname
483 for fname, _ranges in logcmdutil._parselinerangeopt(repo, opts)
484 ]
452 485
453 ui.pager(b'annotate') 486 ui.pager(b'annotate')
454 rootfm = ui.formatter(b'annotate', opts) 487 rootfm = ui.formatter(b'annotate', opts)
455 if ui.debugflag: 488 if ui.debugflag:
456 shorthex = pycompat.identity 489 shorthex = pycompat.identity
552 585
553 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}') 586 fm = rootfm.nested(b'lines', tmpl=b'{rev}: {line}')
554 lines = fctx.annotate( 587 lines = fctx.annotate(
555 follow=follow, skiprevs=skiprevs, diffopts=diffopts 588 follow=follow, skiprevs=skiprevs, diffopts=diffopts
556 ) 589 )
590 if linerange:
591 _fname, (line_start, line_end) = list(
592 logcmdutil._parselinerangeopt(repo, opts)
593 )[0]
594 lines = [
595 line
596 for no, line in enumerate(lines)
597 if line_start <= no < line_end
598 ]
599
557 if not lines: 600 if not lines:
558 fm.end() 601 fm.end()
559 continue 602 continue
560 formats = [] 603 formats = []
561 pieces = [] 604 pieces = []
1357 if opts.get('clean'): 1400 if opts.get('clean'):
1358 label = repo[b'.'].branch() 1401 label = repo[b'.'].branch()
1359 repo.dirstate.setbranch(label, repo.currenttransaction()) 1402 repo.dirstate.setbranch(label, repo.currenttransaction())
1360 ui.status(_(b'reset working directory to branch %s\n') % label) 1403 ui.status(_(b'reset working directory to branch %s\n') % label)
1361 elif label: 1404 elif label:
1362
1363 scmutil.checknewlabel(repo, label, b'branch') 1405 scmutil.checknewlabel(repo, label, b'branch')
1364 if revs: 1406 if revs:
1365 return cmdutil.changebranch(ui, repo, revs, label, **opts) 1407 return cmdutil.changebranch(ui, repo, revs, label, **opts)
1366 1408
1367 if not opts.get('force') and label in repo.branchmap(): 1409 if not opts.get('force') and label in repo.branchmap():