mercurial/commands.py
changeset 34857 84c6b9384d6a
parent 34682 7e3001b74ab3
child 34863 b1e3f609bf45
equal deleted inserted replaced
34856:890afefa7296 34857:84c6b9384d6a
  3232     ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
  3232     ('d', 'date', '', _('show revisions matching date spec'), _('DATE')),
  3233     ('C', 'copies', None, _('show copied files')),
  3233     ('C', 'copies', None, _('show copied files')),
  3234     ('k', 'keyword', [],
  3234     ('k', 'keyword', [],
  3235      _('do case-insensitive search for a given text'), _('TEXT')),
  3235      _('do case-insensitive search for a given text'), _('TEXT')),
  3236     ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
  3236     ('r', 'rev', [], _('show the specified revision or revset'), _('REV')),
       
  3237     ('L', 'line-range', [],
       
  3238      _('follow line range of specified file (EXPERIMENTAL)'),
       
  3239      _('FILE,RANGE')),
  3237     ('', 'removed', None, _('include revisions where files were removed')),
  3240     ('', 'removed', None, _('include revisions where files were removed')),
  3238     ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
  3241     ('m', 'only-merges', None, _('show only merges (DEPRECATED)')),
  3239     ('u', 'user', [], _('revisions committed by user'), _('USER')),
  3242     ('u', 'user', [], _('revisions committed by user'), _('USER')),
  3240     ('', 'only-branch', [],
  3243     ('', 'only-branch', [],
  3241      _('show only changesets within the given named branch (DEPRECATED)'),
  3244      _('show only changesets within the given named branch (DEPRECATED)'),
  3273     and '+' represents a fork where the changeset from the lines below is a
  3276     and '+' represents a fork where the changeset from the lines below is a
  3274     parent of the 'o' merge on the same line.
  3277     parent of the 'o' merge on the same line.
  3275     Paths in the DAG are represented with '|', '/' and so forth. ':' in place
  3278     Paths in the DAG are represented with '|', '/' and so forth. ':' in place
  3276     of a '|' indicates one or more revisions in a path are omitted.
  3279     of a '|' indicates one or more revisions in a path are omitted.
  3277 
  3280 
       
  3281     .. container:: verbose
       
  3282 
       
  3283        Use -L/--line-range FILE,M-N options to follow the history of lines
       
  3284        from M to N in FILE. With -p/--patch only diff hunks affecting
       
  3285        specified line range will be shown. This option requires --follow;
       
  3286        it can be specified multiple times. Currently, this option is not
       
  3287        compatible with --graph. This option is experimental.
       
  3288 
  3278     .. note::
  3289     .. note::
  3279 
  3290 
  3280        :hg:`log --patch` may generate unexpected diff output for merge
  3291        :hg:`log --patch` may generate unexpected diff output for merge
  3281        changesets, as it will only compare the merge changeset against
  3292        changesets, as it will only compare the merge changeset against
  3282        its first parent. Also, only files different from BOTH parents
  3293        its first parent. Also, only files different from BOTH parents
  3288        made on branches and will not show removals or mode changes. To
  3299        made on branches and will not show removals or mode changes. To
  3289        see all such changes, use the --removed switch.
  3300        see all such changes, use the --removed switch.
  3290 
  3301 
  3291     .. container:: verbose
  3302     .. container:: verbose
  3292 
  3303 
       
  3304        .. note::
       
  3305 
       
  3306           The history resulting from -L/--line-range options depends on diff
       
  3307           options; for instance if white-spaces are ignored, respective changes
       
  3308           with only white-spaces in specified line range will not be listed.
       
  3309 
       
  3310     .. container:: verbose
       
  3311 
  3293       Some examples:
  3312       Some examples:
  3294 
  3313 
  3295       - changesets with full descriptions and file lists::
  3314       - changesets with full descriptions and file lists::
  3296 
  3315 
  3297           hg log -v
  3316           hg log -v
  3333           hg log -k alice -d "may 2008 to jul 2008"
  3352           hg log -k alice -d "may 2008 to jul 2008"
  3334 
  3353 
  3335       - summary of all changesets after the last tag::
  3354       - summary of all changesets after the last tag::
  3336 
  3355 
  3337           hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
  3356           hg log -r "last(tagged())::" --template "{desc|firstline}\\n"
       
  3357 
       
  3358       - changesets touching lines 13 to 23 for file.c::
       
  3359 
       
  3360           hg log -L file.c,13-23
       
  3361 
       
  3362       - changesets touching lines 13 to 23 for file.c and lines 2 to 6 of
       
  3363         main.c with patch::
       
  3364 
       
  3365           hg log -L file.c,13-23 -L main.c,2-6 -p
  3338 
  3366 
  3339     See :hg:`help dates` for a list of formats valid for -d/--date.
  3367     See :hg:`help dates` for a list of formats valid for -d/--date.
  3340 
  3368 
  3341     See :hg:`help revisions` for more about specifying and ordering
  3369     See :hg:`help revisions` for more about specifying and ordering
  3342     revisions.
  3370     revisions.
  3348 
  3376 
  3349     Returns 0 on success.
  3377     Returns 0 on success.
  3350 
  3378 
  3351     """
  3379     """
  3352     opts = pycompat.byteskwargs(opts)
  3380     opts = pycompat.byteskwargs(opts)
       
  3381     linerange = opts.get('line_range')
       
  3382 
       
  3383     if linerange and not opts.get('follow'):
       
  3384         raise error.Abort(_('--line-range requires --follow'))
       
  3385 
  3353     if opts.get('follow') and opts.get('rev'):
  3386     if opts.get('follow') and opts.get('rev'):
  3354         opts['rev'] = [revsetlang.formatspec('reverse(::%lr)', opts.get('rev'))]
  3387         opts['rev'] = [revsetlang.formatspec('reverse(::%lr)', opts.get('rev'))]
  3355         del opts['follow']
  3388         del opts['follow']
  3356 
  3389 
  3357     if opts.get('graph'):
  3390     if opts.get('graph'):
       
  3391         if linerange:
       
  3392             raise error.Abort(_('graph not supported with line range patterns'))
  3358         return cmdutil.graphlog(ui, repo, pats, opts)
  3393         return cmdutil.graphlog(ui, repo, pats, opts)
  3359 
  3394 
  3360     revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
  3395     revs, expr, filematcher = cmdutil.getlogrevs(repo, pats, opts)
       
  3396     hunksfilter = None
       
  3397 
       
  3398     if linerange:
       
  3399         revs, lrfilematcher, hunksfilter = cmdutil.getloglinerangerevs(
       
  3400             repo, revs, opts)
       
  3401 
       
  3402         if filematcher is not None and lrfilematcher is not None:
       
  3403             basefilematcher = filematcher
       
  3404 
       
  3405             def filematcher(rev):
       
  3406                 files = (basefilematcher(rev).files()
       
  3407                          + lrfilematcher(rev).files())
       
  3408                 return scmutil.matchfiles(repo, files)
       
  3409 
       
  3410         elif filematcher is None:
       
  3411             filematcher = lrfilematcher
       
  3412 
  3361     limit = cmdutil.loglimit(opts)
  3413     limit = cmdutil.loglimit(opts)
  3362     count = 0
  3414     count = 0
  3363 
  3415 
  3364     getrenamed = None
  3416     getrenamed = None
  3365     if opts.get('copies'):
  3417     if opts.get('copies'):
  3383                     copies.append((fn, rename[0]))
  3435                     copies.append((fn, rename[0]))
  3384         if filematcher:
  3436         if filematcher:
  3385             revmatchfn = filematcher(ctx.rev())
  3437             revmatchfn = filematcher(ctx.rev())
  3386         else:
  3438         else:
  3387             revmatchfn = None
  3439             revmatchfn = None
  3388         displayer.show(ctx, copies=copies, matchfn=revmatchfn)
  3440         if hunksfilter:
       
  3441             revhunksfilter = hunksfilter(rev)
       
  3442         else:
       
  3443             revhunksfilter = None
       
  3444         displayer.show(ctx, copies=copies, matchfn=revmatchfn,
       
  3445                        hunksfilterfn=revhunksfilter)
  3389         if displayer.flush(ctx):
  3446         if displayer.flush(ctx):
  3390             count += 1
  3447             count += 1
  3391 
  3448 
  3392     displayer.close()
  3449     displayer.close()
  3393 
  3450