mercurial/commands.py
changeset 22480 dff638170c48
parent 22479 5d9e46d93c1d
child 22501 bde49bbfb30f
equal deleted inserted replaced
22479:5d9e46d93c1d 22480:dff638170c48
   245     ('f', 'file', None, _('list the filename')),
   245     ('f', 'file', None, _('list the filename')),
   246     ('d', 'date', None, _('list the date (short with -q)')),
   246     ('d', 'date', None, _('list the date (short with -q)')),
   247     ('n', 'number', None, _('list the revision number (default)')),
   247     ('n', 'number', None, _('list the revision number (default)')),
   248     ('c', 'changeset', None, _('list the changeset')),
   248     ('c', 'changeset', None, _('list the changeset')),
   249     ('l', 'line-number', None, _('show line number at the first appearance'))
   249     ('l', 'line-number', None, _('show line number at the first appearance'))
   250     ] + diffwsopts + walkopts,
   250     ] + diffwsopts + walkopts + formatteropts,
   251     _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
   251     _('[-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...'),
   252     inferrepo=True)
   252     inferrepo=True)
   253 def annotate(ui, repo, *pats, **opts):
   253 def annotate(ui, repo, *pats, **opts):
   254     """show changeset information by line for each file
   254     """show changeset information by line for each file
   255 
   255 
   272     if opts.get('follow'):
   272     if opts.get('follow'):
   273         # --follow is deprecated and now just an alias for -f/--file
   273         # --follow is deprecated and now just an alias for -f/--file
   274         # to mimic the behavior of Mercurial before version 1.5
   274         # to mimic the behavior of Mercurial before version 1.5
   275         opts['file'] = True
   275         opts['file'] = True
   276 
   276 
       
   277     fm = ui.formatter('annotate', opts)
   277     datefunc = ui.quiet and util.shortdate or util.datestr
   278     datefunc = ui.quiet and util.shortdate or util.datestr
   278     hexfn = ui.debugflag and hex or short
   279     if fm or ui.debugflag:
       
   280         hexfn = hex
       
   281     else:
       
   282         hexfn = short
   279 
   283 
   280     opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
   284     opmap = [('user', ' ', lambda x: x[0].user(), ui.shortuser),
   281              ('number', ' ', lambda x: x[0].rev(), str),
   285              ('number', ' ', lambda x: x[0].rev(), str),
   282              ('changeset', ' ', lambda x: hexfn(x[0].node()), str),
   286              ('changeset', ' ', lambda x: hexfn(x[0].node()), str),
   283              ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
   287              ('date', ' ', lambda x: x[0].date(), util.cachefunc(datefunc)),
   284              ('file', ' ', lambda x: x[0].path(), str),
   288              ('file', ' ', lambda x: x[0].path(), str),
   285              ('line_number', ':', lambda x: x[1], str),
   289              ('line_number', ':', lambda x: x[1], str),
   286             ]
   290             ]
       
   291     fieldnamemap = {'number': 'rev', 'changeset': 'node'}
   287 
   292 
   288     if (not opts.get('user') and not opts.get('changeset')
   293     if (not opts.get('user') and not opts.get('changeset')
   289         and not opts.get('date') and not opts.get('file')):
   294         and not opts.get('date') and not opts.get('file')):
   290         opts['number'] = True
   295         opts['number'] = True
   291 
   296 
   292     linenumber = opts.get('line_number') is not None
   297     linenumber = opts.get('line_number') is not None
   293     if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
   298     if linenumber and (not opts.get('changeset')) and (not opts.get('number')):
   294         raise util.Abort(_('at least one of -n/-c is required for -l'))
   299         raise util.Abort(_('at least one of -n/-c is required for -l'))
   295 
   300 
   296     def makefunc(get, fmt):
   301     if fm:
   297         return lambda x: fmt(get(x))
   302         def makefunc(get, fmt):
       
   303             return get
       
   304     else:
       
   305         def makefunc(get, fmt):
       
   306             return lambda x: fmt(get(x))
   298     funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
   307     funcmap = [(makefunc(get, fmt), sep) for op, sep, get, fmt in opmap
   299                if opts.get(op)]
   308                if opts.get(op)]
   300     funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
   309     funcmap[0] = (funcmap[0][0], '') # no separator in front of first column
       
   310     fields = ' '.join(fieldnamemap.get(op, op) for op, sep, get, fmt in opmap
       
   311                       if opts.get(op))
   301 
   312 
   302     def bad(x, y):
   313     def bad(x, y):
   303         raise util.Abort("%s: %s" % (x, y))
   314         raise util.Abort("%s: %s" % (x, y))
   304 
   315 
   305     ctx = scmutil.revsingle(repo, opts.get('rev'))
   316     ctx = scmutil.revsingle(repo, opts.get('rev'))
   308     follow = not opts.get('no_follow')
   319     follow = not opts.get('no_follow')
   309     diffopts = patch.diffopts(ui, opts, section='annotate')
   320     diffopts = patch.diffopts(ui, opts, section='annotate')
   310     for abs in ctx.walk(m):
   321     for abs in ctx.walk(m):
   311         fctx = ctx[abs]
   322         fctx = ctx[abs]
   312         if not opts.get('text') and util.binary(fctx.data()):
   323         if not opts.get('text') and util.binary(fctx.data()):
   313             ui.write(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
   324             fm.plain(_("%s: binary file\n") % ((pats and m.rel(abs)) or abs))
   314             continue
   325             continue
   315 
   326 
   316         lines = fctx.annotate(follow=follow, linenumber=linenumber,
   327         lines = fctx.annotate(follow=follow, linenumber=linenumber,
   317                               diffopts=diffopts)
   328                               diffopts=diffopts)
   318         formats = []
   329         formats = []
   319         pieces = []
   330         pieces = []
   320 
   331 
   321         for f, sep in funcmap:
   332         for f, sep in funcmap:
   322             l = [f(n) for n, dummy in lines]
   333             l = [f(n) for n, dummy in lines]
   323             if l:
   334             if l:
   324                 sizes = [encoding.colwidth(x) for x in l]
   335                 if fm:
   325                 ml = max(sizes)
   336                     formats.append(['%s' for x in l])
   326                 formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
   337                 else:
       
   338                     sizes = [encoding.colwidth(x) for x in l]
       
   339                     ml = max(sizes)
       
   340                     formats.append([sep + ' ' * (ml - w) + '%s' for w in sizes])
   327                 pieces.append(l)
   341                 pieces.append(l)
   328 
   342 
   329         for f, p, l in zip(zip(*formats), zip(*pieces), lines):
   343         for f, p, l in zip(zip(*formats), zip(*pieces), lines):
   330             ui.write("".join(f) % p)
   344             fm.startitem()
   331             ui.write(": %s" % l[1])
   345             fm.write(fields, "".join(f), *p)
       
   346             fm.write('line', ": %s", l[1])
   332 
   347 
   333         if lines and not lines[-1][1].endswith('\n'):
   348         if lines and not lines[-1][1].endswith('\n'):
   334             ui.write('\n')
   349             fm.plain('\n')
       
   350 
       
   351     fm.end()
   335 
   352 
   336 @command('archive',
   353 @command('archive',
   337     [('', 'no-decode', None, _('do not pass files through decoders')),
   354     [('', 'no-decode', None, _('do not pass files through decoders')),
   338     ('p', 'prefix', '', _('directory prefix for files in archive'),
   355     ('p', 'prefix', '', _('directory prefix for files in archive'),
   339      _('PREFIX')),
   356      _('PREFIX')),