##// END OF EJS Templates
churn: deprecate -t option in favour of -T...
Jordi Gutiérrez Hermoso -
r24139:73b3218b default
parent child Browse files
Show More
@@ -1,200 +1,202 b''
1 # churn.py - create a graph of revisions count grouped by template
1 # churn.py - create a graph of revisions count grouped by template
2 #
2 #
3 # Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
3 # Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
4 # Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
4 # Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
5 #
5 #
6 # This software may be used and distributed according to the terms of the
6 # This software may be used and distributed according to the terms of the
7 # GNU General Public License version 2 or any later version.
7 # GNU General Public License version 2 or any later version.
8
8
9 '''command to display statistics about repository history'''
9 '''command to display statistics about repository history'''
10
10
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12 from mercurial import patch, cmdutil, scmutil, util, templater, commands
12 from mercurial import patch, cmdutil, scmutil, util, templater, commands
13 from mercurial import encoding
13 from mercurial import encoding
14 import os
14 import os
15 import time, datetime
15 import time, datetime
16
16
17 cmdtable = {}
17 cmdtable = {}
18 command = cmdutil.command(cmdtable)
18 command = cmdutil.command(cmdtable)
19 testedwith = 'internal'
19 testedwith = 'internal'
20
20
21 def maketemplater(ui, repo, tmpl):
21 def maketemplater(ui, repo, tmpl):
22 tmpl = templater.parsestring(tmpl, quoted=False)
22 tmpl = templater.parsestring(tmpl, quoted=False)
23 try:
23 try:
24 t = cmdutil.changeset_templater(ui, repo, False, None, tmpl,
24 t = cmdutil.changeset_templater(ui, repo, False, None, tmpl,
25 None, False)
25 None, False)
26 except SyntaxError, inst:
26 except SyntaxError, inst:
27 raise util.Abort(inst.args[0])
27 raise util.Abort(inst.args[0])
28 return t
28 return t
29
29
30 def changedlines(ui, repo, ctx1, ctx2, fns):
30 def changedlines(ui, repo, ctx1, ctx2, fns):
31 added, removed = 0, 0
31 added, removed = 0, 0
32 fmatch = scmutil.matchfiles(repo, fns)
32 fmatch = scmutil.matchfiles(repo, fns)
33 diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
33 diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
34 for l in diff.split('\n'):
34 for l in diff.split('\n'):
35 if l.startswith("+") and not l.startswith("+++ "):
35 if l.startswith("+") and not l.startswith("+++ "):
36 added += 1
36 added += 1
37 elif l.startswith("-") and not l.startswith("--- "):
37 elif l.startswith("-") and not l.startswith("--- "):
38 removed += 1
38 removed += 1
39 return (added, removed)
39 return (added, removed)
40
40
41 def countrate(ui, repo, amap, *pats, **opts):
41 def countrate(ui, repo, amap, *pats, **opts):
42 """Calculate stats"""
42 """Calculate stats"""
43 if opts.get('dateformat'):
43 if opts.get('dateformat'):
44 def getkey(ctx):
44 def getkey(ctx):
45 t, tz = ctx.date()
45 t, tz = ctx.date()
46 date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
46 date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
47 return date.strftime(opts['dateformat'])
47 return date.strftime(opts['dateformat'])
48 else:
48 else:
49 tmpl = opts.get('template', '{author|email}')
49 tmpl = opts.get('oldtemplate') or opts.get('template')
50 tmpl = maketemplater(ui, repo, tmpl)
50 tmpl = maketemplater(ui, repo, tmpl)
51 def getkey(ctx):
51 def getkey(ctx):
52 ui.pushbuffer()
52 ui.pushbuffer()
53 tmpl.show(ctx)
53 tmpl.show(ctx)
54 return ui.popbuffer()
54 return ui.popbuffer()
55
55
56 state = {'count': 0}
56 state = {'count': 0}
57 rate = {}
57 rate = {}
58 df = False
58 df = False
59 if opts.get('date'):
59 if opts.get('date'):
60 df = util.matchdate(opts['date'])
60 df = util.matchdate(opts['date'])
61
61
62 m = scmutil.match(repo[None], pats, opts)
62 m = scmutil.match(repo[None], pats, opts)
63 def prep(ctx, fns):
63 def prep(ctx, fns):
64 rev = ctx.rev()
64 rev = ctx.rev()
65 if df and not df(ctx.date()[0]): # doesn't match date format
65 if df and not df(ctx.date()[0]): # doesn't match date format
66 return
66 return
67
67
68 key = getkey(ctx).strip()
68 key = getkey(ctx).strip()
69 key = amap.get(key, key) # alias remap
69 key = amap.get(key, key) # alias remap
70 if opts.get('changesets'):
70 if opts.get('changesets'):
71 rate[key] = (rate.get(key, (0,))[0] + 1, 0)
71 rate[key] = (rate.get(key, (0,))[0] + 1, 0)
72 else:
72 else:
73 parents = ctx.parents()
73 parents = ctx.parents()
74 if len(parents) > 1:
74 if len(parents) > 1:
75 ui.note(_('revision %d is a merge, ignoring...\n') % (rev,))
75 ui.note(_('revision %d is a merge, ignoring...\n') % (rev,))
76 return
76 return
77
77
78 ctx1 = parents[0]
78 ctx1 = parents[0]
79 lines = changedlines(ui, repo, ctx1, ctx, fns)
79 lines = changedlines(ui, repo, ctx1, ctx, fns)
80 rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
80 rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
81
81
82 state['count'] += 1
82 state['count'] += 1
83 ui.progress(_('analyzing'), state['count'], total=len(repo))
83 ui.progress(_('analyzing'), state['count'], total=len(repo))
84
84
85 for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
85 for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
86 continue
86 continue
87
87
88 ui.progress(_('analyzing'), None)
88 ui.progress(_('analyzing'), None)
89
89
90 return rate
90 return rate
91
91
92
92
93 @command('churn',
93 @command('churn',
94 [('r', 'rev', [],
94 [('r', 'rev', [],
95 _('count rate for the specified revision or revset'), _('REV')),
95 _('count rate for the specified revision or revset'), _('REV')),
96 ('d', 'date', '',
96 ('d', 'date', '',
97 _('count rate for revisions matching date spec'), _('DATE')),
97 _('count rate for revisions matching date spec'), _('DATE')),
98 ('t', 'template', '{author|email}',
98 ('t', 'oldtemplate', '',
99 _('template to group changesets (DEPRECATED)'), _('TEMPLATE')),
100 ('T', 'template', '{author|email}',
99 _('template to group changesets'), _('TEMPLATE')),
101 _('template to group changesets'), _('TEMPLATE')),
100 ('f', 'dateformat', '',
102 ('f', 'dateformat', '',
101 _('strftime-compatible format for grouping by date'), _('FORMAT')),
103 _('strftime-compatible format for grouping by date'), _('FORMAT')),
102 ('c', 'changesets', False, _('count rate by number of changesets')),
104 ('c', 'changesets', False, _('count rate by number of changesets')),
103 ('s', 'sort', False, _('sort by key (default: sort by count)')),
105 ('s', 'sort', False, _('sort by key (default: sort by count)')),
104 ('', 'diffstat', False, _('display added/removed lines separately')),
106 ('', 'diffstat', False, _('display added/removed lines separately')),
105 ('', 'aliases', '', _('file with email aliases'), _('FILE')),
107 ('', 'aliases', '', _('file with email aliases'), _('FILE')),
106 ] + commands.walkopts,
108 ] + commands.walkopts,
107 _("hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]"),
109 _("hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]"),
108 inferrepo=True)
110 inferrepo=True)
109 def churn(ui, repo, *pats, **opts):
111 def churn(ui, repo, *pats, **opts):
110 '''histogram of changes to the repository
112 '''histogram of changes to the repository
111
113
112 This command will display a histogram representing the number
114 This command will display a histogram representing the number
113 of changed lines or revisions, grouped according to the given
115 of changed lines or revisions, grouped according to the given
114 template. The default template will group changes by author.
116 template. The default template will group changes by author.
115 The --dateformat option may be used to group the results by
117 The --dateformat option may be used to group the results by
116 date instead.
118 date instead.
117
119
118 Statistics are based on the number of changed lines, or
120 Statistics are based on the number of changed lines, or
119 alternatively the number of matching revisions if the
121 alternatively the number of matching revisions if the
120 --changesets option is specified.
122 --changesets option is specified.
121
123
122 Examples::
124 Examples::
123
125
124 # display count of changed lines for every committer
126 # display count of changed lines for every committer
125 hg churn -t "{author|email}"
127 hg churn -t "{author|email}"
126
128
127 # display daily activity graph
129 # display daily activity graph
128 hg churn -f "%H" -s -c
130 hg churn -f "%H" -s -c
129
131
130 # display activity of developers by month
132 # display activity of developers by month
131 hg churn -f "%Y-%m" -s -c
133 hg churn -f "%Y-%m" -s -c
132
134
133 # display count of lines changed in every year
135 # display count of lines changed in every year
134 hg churn -f "%Y" -s
136 hg churn -f "%Y" -s
135
137
136 It is possible to map alternate email addresses to a main address
138 It is possible to map alternate email addresses to a main address
137 by providing a file using the following format::
139 by providing a file using the following format::
138
140
139 <alias email> = <actual email>
141 <alias email> = <actual email>
140
142
141 Such a file may be specified with the --aliases option, otherwise
143 Such a file may be specified with the --aliases option, otherwise
142 a .hgchurn file will be looked for in the working directory root.
144 a .hgchurn file will be looked for in the working directory root.
143 Aliases will be split from the rightmost "=".
145 Aliases will be split from the rightmost "=".
144 '''
146 '''
145 def pad(s, l):
147 def pad(s, l):
146 return s + " " * (l - encoding.colwidth(s))
148 return s + " " * (l - encoding.colwidth(s))
147
149
148 amap = {}
150 amap = {}
149 aliases = opts.get('aliases')
151 aliases = opts.get('aliases')
150 if not aliases and os.path.exists(repo.wjoin('.hgchurn')):
152 if not aliases and os.path.exists(repo.wjoin('.hgchurn')):
151 aliases = repo.wjoin('.hgchurn')
153 aliases = repo.wjoin('.hgchurn')
152 if aliases:
154 if aliases:
153 for l in open(aliases, "r"):
155 for l in open(aliases, "r"):
154 try:
156 try:
155 alias, actual = l.rsplit('=' in l and '=' or None, 1)
157 alias, actual = l.rsplit('=' in l and '=' or None, 1)
156 amap[alias.strip()] = actual.strip()
158 amap[alias.strip()] = actual.strip()
157 except ValueError:
159 except ValueError:
158 l = l.strip()
160 l = l.strip()
159 if l:
161 if l:
160 ui.warn(_("skipping malformed alias: %s\n") % l)
162 ui.warn(_("skipping malformed alias: %s\n") % l)
161 continue
163 continue
162
164
163 rate = countrate(ui, repo, amap, *pats, **opts).items()
165 rate = countrate(ui, repo, amap, *pats, **opts).items()
164 if not rate:
166 if not rate:
165 return
167 return
166
168
167 if opts.get('sort'):
169 if opts.get('sort'):
168 rate.sort()
170 rate.sort()
169 else:
171 else:
170 rate.sort(key=lambda x: (-sum(x[1]), x))
172 rate.sort(key=lambda x: (-sum(x[1]), x))
171
173
172 # Be careful not to have a zero maxcount (issue833)
174 # Be careful not to have a zero maxcount (issue833)
173 maxcount = float(max(sum(v) for k, v in rate)) or 1.0
175 maxcount = float(max(sum(v) for k, v in rate)) or 1.0
174 maxname = max(len(k) for k, v in rate)
176 maxname = max(len(k) for k, v in rate)
175
177
176 ttywidth = ui.termwidth()
178 ttywidth = ui.termwidth()
177 ui.debug("assuming %i character terminal\n" % ttywidth)
179 ui.debug("assuming %i character terminal\n" % ttywidth)
178 width = ttywidth - maxname - 2 - 2 - 2
180 width = ttywidth - maxname - 2 - 2 - 2
179
181
180 if opts.get('diffstat'):
182 if opts.get('diffstat'):
181 width -= 15
183 width -= 15
182 def format(name, diffstat):
184 def format(name, diffstat):
183 added, removed = diffstat
185 added, removed = diffstat
184 return "%s %15s %s%s\n" % (pad(name, maxname),
186 return "%s %15s %s%s\n" % (pad(name, maxname),
185 '+%d/-%d' % (added, removed),
187 '+%d/-%d' % (added, removed),
186 ui.label('+' * charnum(added),
188 ui.label('+' * charnum(added),
187 'diffstat.inserted'),
189 'diffstat.inserted'),
188 ui.label('-' * charnum(removed),
190 ui.label('-' * charnum(removed),
189 'diffstat.deleted'))
191 'diffstat.deleted'))
190 else:
192 else:
191 width -= 6
193 width -= 6
192 def format(name, count):
194 def format(name, count):
193 return "%s %6d %s\n" % (pad(name, maxname), sum(count),
195 return "%s %6d %s\n" % (pad(name, maxname), sum(count),
194 '*' * charnum(sum(count)))
196 '*' * charnum(sum(count)))
195
197
196 def charnum(count):
198 def charnum(count):
197 return int(round(count * width / maxcount))
199 return int(round(count * width / maxcount))
198
200
199 for name, count in rate:
201 for name, count in rate:
200 ui.write(format(name, count))
202 ui.write(format(name, count))
@@ -1,174 +1,197 b''
1 $ echo "[extensions]" >> $HGRCPATH
1 $ echo "[extensions]" >> $HGRCPATH
2 $ echo "churn=" >> $HGRCPATH
2 $ echo "churn=" >> $HGRCPATH
3
3
4 create test repository
4 create test repository
5
5
6 $ hg init repo
6 $ hg init repo
7 $ cd repo
7 $ cd repo
8 $ echo a > a
8 $ echo a > a
9 $ hg ci -Am adda -u user1 -d 6:00
9 $ hg ci -Am adda -u user1 -d 6:00
10 adding a
10 adding a
11 $ echo b >> a
11 $ echo b >> a
12 $ echo b > b
12 $ echo b > b
13 $ hg ci -m changeba -u user2 -d 9:00 a
13 $ hg ci -m changeba -u user2 -d 9:00 a
14 $ hg ci -Am addb -u user2 -d 9:30
14 $ hg ci -Am addb -u user2 -d 9:30
15 adding b
15 adding b
16 $ echo c >> a
16 $ echo c >> a
17 $ echo c >> b
17 $ echo c >> b
18 $ echo c > c
18 $ echo c > c
19 $ hg ci -m changeca -u user3 -d 12:00 a
19 $ hg ci -m changeca -u user3 -d 12:00 a
20 $ hg ci -m changecb -u user3 -d 12:15 b
20 $ hg ci -m changecb -u user3 -d 12:15 b
21 $ hg ci -Am addc -u user3 -d 12:30
21 $ hg ci -Am addc -u user3 -d 12:30
22 adding c
22 adding c
23 $ mkdir -p d/e
23 $ mkdir -p d/e
24 $ echo abc > d/e/f1.txt
24 $ echo abc > d/e/f1.txt
25 $ hg ci -Am "add d/e/f1.txt" -u user1 -d 12:45 d/e/f1.txt
25 $ hg ci -Am "add d/e/f1.txt" -u user1 -d 12:45 d/e/f1.txt
26 $ mkdir -p d/g
26 $ mkdir -p d/g
27 $ echo def > d/g/f2.txt
27 $ echo def > d/g/f2.txt
28 $ hg ci -Am "add d/g/f2.txt" -u user1 -d 13:00 d/g/f2.txt
28 $ hg ci -Am "add d/g/f2.txt" -u user1 -d 13:00 d/g/f2.txt
29
29
30
30
31 churn separate directories
31 churn separate directories
32
32
33 $ cd d
33 $ cd d
34 $ hg churn e
34 $ hg churn e
35 user1 1 ***************************************************************
35 user1 1 ***************************************************************
36
36
37 churn all
37 churn all
38
38
39 $ hg churn
39 $ hg churn
40 user1 3 ***************************************************************
40 user1 3 ***************************************************************
41 user3 3 ***************************************************************
41 user3 3 ***************************************************************
42 user2 2 ******************************************
42 user2 2 ******************************************
43
43
44 churn excluding one dir
44 churn excluding one dir
45
45
46 $ hg churn -X e
46 $ hg churn -X e
47 user3 3 ***************************************************************
47 user3 3 ***************************************************************
48 user1 2 ******************************************
48 user1 2 ******************************************
49 user2 2 ******************************************
49 user2 2 ******************************************
50
50
51 churn up to rev 2
51 churn up to rev 2
52
52
53 $ hg churn -r :2
53 $ hg churn -r :2
54 user2 2 ***************************************************************
54 user2 2 ***************************************************************
55 user1 1 ********************************
55 user1 1 ********************************
56 $ cd ..
56 $ cd ..
57
57
58 churn with aliases
58 churn with aliases
59
59
60 $ cat > ../aliases <<EOF
60 $ cat > ../aliases <<EOF
61 > user1 alias1
61 > user1 alias1
62 > user3 alias3
62 > user3 alias3
63 > not-an-alias
63 > not-an-alias
64 > EOF
64 > EOF
65
65
66 churn with .hgchurn
66 churn with .hgchurn
67
67
68 $ mv ../aliases .hgchurn
68 $ mv ../aliases .hgchurn
69 $ hg churn
69 $ hg churn
70 skipping malformed alias: not-an-alias
70 skipping malformed alias: not-an-alias
71 alias1 3 **************************************************************
71 alias1 3 **************************************************************
72 alias3 3 **************************************************************
72 alias3 3 **************************************************************
73 user2 2 *****************************************
73 user2 2 *****************************************
74 $ rm .hgchurn
74 $ rm .hgchurn
75
75
76 churn with column specifier
76 churn with column specifier
77
77
78 $ COLUMNS=40 hg churn
78 $ COLUMNS=40 hg churn
79 user1 3 ***********************
79 user1 3 ***********************
80 user3 3 ***********************
80 user3 3 ***********************
81 user2 2 ***************
81 user2 2 ***************
82
82
83 churn by hour
83 churn by hour
84
84
85 $ hg churn -f '%H' -s
85 $ hg churn -f '%H' -s
86 06 1 *****************
86 06 1 *****************
87 09 2 *********************************
87 09 2 *********************************
88 12 4 ******************************************************************
88 12 4 ******************************************************************
89 13 1 *****************
89 13 1 *****************
90
90
91
91
92 churn with separated added/removed lines
92 churn with separated added/removed lines
93
93
94 $ hg rm d/g/f2.txt
94 $ hg rm d/g/f2.txt
95 $ hg ci -Am "removed d/g/f2.txt" -u user1 -d 14:00 d/g/f2.txt
95 $ hg ci -Am "removed d/g/f2.txt" -u user1 -d 14:00 d/g/f2.txt
96 $ hg churn --diffstat
96 $ hg churn --diffstat
97 user1 +3/-1 +++++++++++++++++++++++++++++++++++++++++--------------
97 user1 +3/-1 +++++++++++++++++++++++++++++++++++++++++--------------
98 user3 +3/-0 +++++++++++++++++++++++++++++++++++++++++
98 user3 +3/-0 +++++++++++++++++++++++++++++++++++++++++
99 user2 +2/-0 +++++++++++++++++++++++++++
99 user2 +2/-0 +++++++++++++++++++++++++++
100
100
101 churn --diffstat with color
101 churn --diffstat with color
102
102
103 $ hg --config extensions.color= churn --config color.mode=ansi \
103 $ hg --config extensions.color= churn --config color.mode=ansi \
104 > --diffstat --color=always
104 > --diffstat --color=always
105 user1 +3/-1 \x1b[0;32m+++++++++++++++++++++++++++++++++++++++++\x1b[0m\x1b[0;31m--------------\x1b[0m (esc)
105 user1 +3/-1 \x1b[0;32m+++++++++++++++++++++++++++++++++++++++++\x1b[0m\x1b[0;31m--------------\x1b[0m (esc)
106 user3 +3/-0 \x1b[0;32m+++++++++++++++++++++++++++++++++++++++++\x1b[0m (esc)
106 user3 +3/-0 \x1b[0;32m+++++++++++++++++++++++++++++++++++++++++\x1b[0m (esc)
107 user2 +2/-0 \x1b[0;32m+++++++++++++++++++++++++++\x1b[0m (esc)
107 user2 +2/-0 \x1b[0;32m+++++++++++++++++++++++++++\x1b[0m (esc)
108
108
109
109
110 changeset number churn
110 changeset number churn
111
111
112 $ hg churn -c
112 $ hg churn -c
113 user1 4 ***************************************************************
113 user1 4 ***************************************************************
114 user3 3 ***********************************************
114 user3 3 ***********************************************
115 user2 2 ********************************
115 user2 2 ********************************
116
116
117 $ echo 'with space = no-space' >> ../aliases
117 $ echo 'with space = no-space' >> ../aliases
118 $ echo a >> a
118 $ echo a >> a
119 $ hg commit -m a -u 'with space' -d 15:00
119 $ hg commit -m a -u 'with space' -d 15:00
120
120
121 churn with space in alias
121 churn with space in alias
122
122
123 $ hg churn --aliases ../aliases -r tip
123 $ hg churn --aliases ../aliases -r tip
124 no-space 1 ************************************************************
124 no-space 1 ************************************************************
125
125
126 $ cd ..
126 $ cd ..
127
127
128
128
129 Issue833: ZeroDivisionError
129 Issue833: ZeroDivisionError
130
130
131 $ hg init issue-833
131 $ hg init issue-833
132 $ cd issue-833
132 $ cd issue-833
133 $ touch foo
133 $ touch foo
134 $ hg ci -Am foo
134 $ hg ci -Am foo
135 adding foo
135 adding foo
136
136
137 this was failing with a ZeroDivisionError
137 this was failing with a ZeroDivisionError
138
138
139 $ hg churn
139 $ hg churn
140 test 0
140 test 0
141 $ cd ..
141 $ cd ..
142
142
143 Ignore trailing or leading spaces in emails
143 Ignore trailing or leading spaces in emails
144
144
145 $ cd repo
145 $ cd repo
146 $ touch bar
146 $ touch bar
147 $ hg ci -Am'bar' -u 'user4 <user4@x.com>'
147 $ hg ci -Am'bar' -u 'user4 <user4@x.com>'
148 adding bar
148 adding bar
149 $ touch foo
149 $ touch foo
150 $ hg ci -Am'foo' -u 'user4 < user4@x.com >'
150 $ hg ci -Am'foo' -u 'user4 < user4@x.com >'
151 adding foo
151 adding foo
152 $ hg log -l2 --template '[{author|email}]\n'
152 $ hg log -l2 --template '[{author|email}]\n'
153 [ user4@x.com ]
153 [ user4@x.com ]
154 [user4@x.com]
154 [user4@x.com]
155 $ hg churn -c
155 $ hg churn -c
156 user1 4 *********************************************************
156 user1 4 *********************************************************
157 user3 3 *******************************************
157 user3 3 *******************************************
158 user2 2 *****************************
158 user2 2 *****************************
159 user4@x.com 2 *****************************
159 user4@x.com 2 *****************************
160 with space 1 **************
160 with space 1 **************
161
161
162 Test multibyte sequences in names
162 Test multibyte sequences in names
163
163
164 $ echo bar >> bar
164 $ echo bar >> bar
165 $ hg --encoding utf-8 ci -m'changed bar' -u 'El Niño <nino@x.com>'
165 $ hg --encoding utf-8 ci -m'changed bar' -u 'El Niño <nino@x.com>'
166 $ hg --encoding utf-8 churn -ct '{author|person}'
166 $ hg --encoding utf-8 churn -ct '{author|person}'
167 user1 4 **********************************************************
167 user1 4 **********************************************************
168 user3 3 ********************************************
168 user3 3 ********************************************
169 user2 2 *****************************
169 user2 2 *****************************
170 user4 2 *****************************
170 user4 2 *****************************
171 El Ni\xc3\xb1o 1 *************** (esc)
171 El Ni\xc3\xb1o 1 *************** (esc)
172 with space 1 ***************
172 with space 1 ***************
173
173
174 Test --template argument, with backwards compatiblity
175
176 $ hg churn -t '{author|user}'
177 user1 4 ***************************************************************
178 user3 3 ***********************************************
179 user2 2 ********************************
180 nino 1 ****************
181 with 1 ****************
182 0
183 user4 0
184 $ hg churn -T '{author|user}'
185 user1 4 ***************************************************************
186 user3 3 ***********************************************
187 user2 2 ********************************
188 nino 1 ****************
189 with 1 ****************
190 0
191 user4 0
192 $ hg churn -t 'alltogether'
193 alltogether 11 *********************************************************
194 $ hg churn -T 'alltogether'
195 alltogether 11 *********************************************************
196
174 $ cd ..
197 $ cd ..
General Comments 0
You need to be logged in to leave comments. Login now