68 |
68 |
69 Without the -a option, annotate will avoid processing files it |
69 Without the -a option, annotate will avoid processing files it |
70 detects as binary. With -a, annotate will generate an annotation |
70 detects as binary. With -a, annotate will generate an annotation |
71 anyway, probably with undesirable results. |
71 anyway, probably with undesirable results. |
72 """ |
72 """ |
73 getdate = util.cachefunc(lambda x: util.datestr(x.date())) |
73 getdate = util.cachefunc(lambda x: util.datestr(x[0].date())) |
74 |
74 |
75 if not pats: |
75 if not pats: |
76 raise util.Abort(_('at least one file name or pattern required')) |
76 raise util.Abort(_('at least one file name or pattern required')) |
77 |
77 |
78 opmap = [['user', lambda x: ui.shortuser(x.user())], |
78 opmap = [('user', lambda x: ui.shortuser(x[0].user())), |
79 ['number', lambda x: str(x.rev())], |
79 ('number', lambda x: str(x[0].rev())), |
80 ['changeset', lambda x: short(x.node())], |
80 ('changeset', lambda x: short(x[0].node())), |
81 ['date', getdate], ['follow', lambda x: x.path()]] |
81 ('date', getdate), |
|
82 ('follow', lambda x: x[0].path()), |
|
83 ] |
|
84 |
82 if (not opts['user'] and not opts['changeset'] and not opts['date'] |
85 if (not opts['user'] and not opts['changeset'] and not opts['date'] |
83 and not opts['follow']): |
86 and not opts['follow']): |
84 opts['number'] = 1 |
87 opts['number'] = 1 |
|
88 |
|
89 linenumber = opts.get('line_number') is not None |
|
90 if (linenumber and (not opts['changeset']) and (not opts['number'])): |
|
91 raise util.Abort(_('at least one of -n/-c is required for -l')) |
|
92 |
|
93 funcmap = [func for op, func in opmap if opts.get(op)] |
|
94 if linenumber: |
|
95 lastfunc = funcmap[-1] |
|
96 funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1]) |
85 |
97 |
86 ctx = repo.changectx(opts['rev']) |
98 ctx = repo.changectx(opts['rev']) |
87 |
99 |
88 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, |
100 for src, abs, rel, exact in cmdutil.walk(repo, pats, opts, |
89 node=ctx.node()): |
101 node=ctx.node()): |
90 fctx = ctx.filectx(abs) |
102 fctx = ctx.filectx(abs) |
91 if not opts['text'] and util.binary(fctx.data()): |
103 if not opts['text'] and util.binary(fctx.data()): |
92 ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) |
104 ui.write(_("%s: binary file\n") % ((pats and rel) or abs)) |
93 continue |
105 continue |
94 |
106 |
95 lines = fctx.annotate(follow=opts.get('follow')) |
107 lines = fctx.annotate(follow=opts.get('follow'), |
|
108 linenumber=linenumber) |
96 pieces = [] |
109 pieces = [] |
97 |
110 |
98 for o, f in opmap: |
111 for f in funcmap: |
99 if opts[o]: |
112 l = [f(n) for n, dummy in lines] |
100 l = [f(n) for n, dummy in lines] |
113 if l: |
101 if l: |
114 m = max(map(len, l)) |
102 m = max(map(len, l)) |
115 pieces.append(["%*s" % (m, x) for x in l]) |
103 pieces.append(["%*s" % (m, x) for x in l]) |
|
104 |
116 |
105 if pieces: |
117 if pieces: |
106 for p, l in zip(zip(*pieces), lines): |
118 for p, l in zip(zip(*pieces), lines): |
107 ui.write("%s: %s" % (" ".join(p), l[1])) |
119 ui.write("%s: %s" % (" ".join(p), l[1])) |
108 |
120 |
2755 ('a', 'text', None, _('treat all files as text')), |
2767 ('a', 'text', None, _('treat all files as text')), |
2756 ('u', 'user', None, _('list the author')), |
2768 ('u', 'user', None, _('list the author')), |
2757 ('d', 'date', None, _('list the date')), |
2769 ('d', 'date', None, _('list the date')), |
2758 ('n', 'number', None, _('list the revision number (default)')), |
2770 ('n', 'number', None, _('list the revision number (default)')), |
2759 ('c', 'changeset', None, _('list the changeset')), |
2771 ('c', 'changeset', None, _('list the changeset')), |
|
2772 ('l', 'line-number', None, |
|
2773 _('show line number at the first appearance')) |
2760 ] + walkopts, |
2774 ] + walkopts, |
2761 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] FILE...')), |
2775 _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')), |
2762 "archive": |
2776 "archive": |
2763 (archive, |
2777 (archive, |
2764 [('', 'no-decode', None, _('do not pass files through decoders')), |
2778 [('', 'no-decode', None, _('do not pass files through decoders')), |
2765 ('p', 'prefix', '', _('directory prefix for files in archive')), |
2779 ('p', 'prefix', '', _('directory prefix for files in archive')), |
2766 ('r', 'rev', '', _('revision to distribute')), |
2780 ('r', 'rev', '', _('revision to distribute')), |