changeset 4847:2192001e4bb4

Add --line-number option to hg annotate (issue506) Line numbers are separated from the last annotation element with a colon, like with many other commands, e.g. (hg) grep or compiler errors. Idea and tests by FUJIWARA Katsunori.
author Thomas Arendsen Hein <thomas@intevation.de>
date Sun, 08 Jul 2007 19:59:02 +0200
parents e45c5120ca27
children 30762680fcd2
files mercurial/commands.py tests/test-annotate tests/test-annotate.out
diffstat 3 files changed, 106 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/commands.py
+++ b/mercurial/commands.py
@@ -70,19 +70,31 @@ def annotate(ui, repo, *pats, **opts):
     detects as binary. With -a, annotate will generate an annotation
     anyway, probably with undesirable results.
     """
-    getdate = util.cachefunc(lambda x: util.datestr(x.date()))
+    getdate = util.cachefunc(lambda x: util.datestr(x[0].date()))
 
     if not pats:
         raise util.Abort(_('at least one file name or pattern required'))
 
-    opmap = [['user', lambda x: ui.shortuser(x.user())],
-             ['number', lambda x: str(x.rev())],
-             ['changeset', lambda x: short(x.node())],
-             ['date', getdate], ['follow', lambda x: x.path()]]
+    opmap = [('user', lambda x: ui.shortuser(x[0].user())),
+             ('number', lambda x: str(x[0].rev())),
+             ('changeset', lambda x: short(x[0].node())),
+             ('date', getdate),
+             ('follow', lambda x: x[0].path()),
+            ]
+
     if (not opts['user'] and not opts['changeset'] and not opts['date']
         and not opts['follow']):
         opts['number'] = 1
 
+    linenumber = opts.get('line_number') is not None
+    if (linenumber and (not opts['changeset']) and (not opts['number'])):
+        raise util.Abort(_('at least one of -n/-c is required for -l'))
+
+    funcmap = [func for op, func in opmap if opts.get(op)]
+    if linenumber:
+        lastfunc = funcmap[-1]
+        funcmap[-1] = lambda x: "%s:%s" % (lastfunc(x), x[1])
+
     ctx = repo.changectx(opts['rev'])
 
     for src, abs, rel, exact in cmdutil.walk(repo, pats, opts,
@@ -92,15 +104,15 @@ def annotate(ui, repo, *pats, **opts):
             ui.write(_("%s: binary file\n") % ((pats and rel) or abs))
             continue
 
-        lines = fctx.annotate(follow=opts.get('follow'))
+        lines = fctx.annotate(follow=opts.get('follow'),
+                              linenumber=linenumber)
         pieces = []
 
-        for o, f in opmap:
-            if opts[o]:
-                l = [f(n) for n, dummy in lines]
-                if l:
-                    m = max(map(len, l))
-                    pieces.append(["%*s" % (m, x) for x in l])
+        for f in funcmap:
+            l = [f(n) for n, dummy in lines]
+            if l:
+                m = max(map(len, l))
+                pieces.append(["%*s" % (m, x) for x in l])
 
         if pieces:
             for p, l in zip(zip(*pieces), lines):
@@ -2757,8 +2769,10 @@ table = {
           ('d', 'date', None, _('list the date')),
           ('n', 'number', None, _('list the revision number (default)')),
           ('c', 'changeset', None, _('list the changeset')),
+          ('l', 'line-number', None,
+           _('show line number at the first appearance'))
          ] + walkopts,
-         _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] FILE...')),
+         _('hg annotate [-r REV] [-f] [-a] [-u] [-d] [-n] [-c] [-l] FILE...')),
     "archive":
         (archive,
          [('', 'no-decode', None, _('do not pass files through decoders')),
--- a/tests/test-annotate
+++ b/tests/test-annotate
@@ -12,18 +12,27 @@ hg ci -A -m test -u nobody -d '1 0'
 echo % annotate -c
 hg annotate -c a
 
+echo % annotate -cl
+hg annotate -cl a
+
 echo % annotate -d
 hg annotate -d a
 
 echo % annotate -n
 hg annotate -n a
 
+echo % annotate -nl
+hg annotate -nl a
+
 echo % annotate -u
 hg annotate -u a
 
 echo % annotate -cdnu
 hg annotate -cdnu a
 
+echo % annotate -cdnul
+hg annotate -cdnul a
+
 cat <<EOF >>a
 a
 a
@@ -32,28 +41,34 @@ hg ci -ma1 -d '1 0'
 hg cp a b
 hg ci -mb -d '1 0'
 cat <<EOF >> b
-b
-b
-b
+b4
+b5
+b6
 EOF
 hg ci -mb2 -d '2 0'
 
-echo % annotate b
-hg annotate b
+echo % annotate -n b
+hg annotate -n b
+echo % annotate -nl b
+hg annotate -nl b
 echo % annotate -nf b
 hg annotate -nf b
+echo % annotate -nlf b
+hg annotate -nlf b
 
 hg up -C 2
 cat <<EOF >> b
-b
+b4
 c
-b
+b5
 EOF
 hg ci -mb2.1 -d '2 0'
 hg merge
 hg ci -mmergeb -d '3 0'
 echo % annotate after merge
 hg annotate -nf b
+echo % annotate after merge with -l
+hg annotate -nlf b
 
 hg up -C 1
 hg cp a b
@@ -65,17 +80,21 @@ EOF
 hg ci -mc -d '3 0'
 hg merge
 cat <<EOF >> b
-b
+b4
 c
-b
+b5
 EOF
 echo d >> b
 hg ci -mmerge2 -d '4 0'
 echo % annotate after rename merge
 hg annotate -nf b
+echo % annotate after rename merge with -l
+hg annotate -nlf b
 
 echo % linkrev vs rev
-hg annotate -r tip a
+hg annotate -r tip -n a
+echo % linkrev vs rev with -l
+hg annotate -r tip -nl a
 
 # test issue 589
 # annotate was crashing when trying to --follow something
--- a/tests/test-annotate.out
+++ b/tests/test-annotate.out
@@ -3,28 +3,48 @@
 adding a
 % annotate -c
 8435f90966e4: a
+% annotate -cl
+8435f90966e4:1: a
 % annotate -d
 Thu Jan 01 00:00:01 1970 +0000: a
 % annotate -n
 0: a
+% annotate -nl
+0:1: a
 % annotate -u
 nobody: a
 % annotate -cdnu
 nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000: a
-% annotate b
+% annotate -cdnul
+nobody 0 8435f90966e4 Thu Jan 01 00:00:01 1970 +0000:1: a
+% annotate -n b
 2: a
 2: a
 2: a
-3: b
-3: b
-3: b
+3: b4
+3: b5
+3: b6
+% annotate -nl b
+2:1: a
+2:2: a
+2:3: a
+3:4: b4
+3:5: b5
+3:6: b6
 % annotate -nf b
 0 a: a
 1 a: a
 1 a: a
-3 b: b
-3 b: b
-3 b: b
+3 b: b4
+3 b: b5
+3 b: b6
+% annotate -nlf b
+0 a:1: a
+1 a:2: a
+1 a:3: a
+3 b:4: b4
+3 b:5: b5
+3 b:6: b6
 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
 merging b
 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
@@ -33,9 +53,16 @@ 0 files updated, 1 files merged, 0 files
 0 a: a
 1 a: a
 1 a: a
-3 b: b
+3 b: b4
 4 b: c
-3 b: b
+3 b: b5
+% annotate after merge with -l
+0 a:1: a
+1 a:2: a
+1 a:3: a
+3 b:4: b4
+4 b:5: c
+3 b:5: b5
 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
 merging b
 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
@@ -44,14 +71,26 @@ 0 files updated, 1 files merged, 0 files
 0 a: a
 6 b: z
 1 a: a
-3 b: b
+3 b: b4
 4 b: c
-3 b: b
+3 b: b5
 7 b: d
+% annotate after rename merge with -l
+0 a:1: a
+6 b:2: z
+1 a:3: a
+3 b:4: b4
+4 b:5: c
+3 b:5: b5
+7 b:7: d
 % linkrev vs rev
 0: a
 1: a
 1: a
+% linkrev vs rev with -l
+0:1: a
+1:2: a
+1:3: a
 % generate ABA rename configuration
 % annotate after ABA with follow
 foo: foo