##// END OF EJS Templates
churn: use ui.progress instead of --progress
Eric Eisner -
r10647:4ba41eeb default
parent child Browse files
Show More
@@ -1,193 +1,186
1 1 # churn.py - create a graph of revisions count grouped by template
2 2 #
3 3 # Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
4 4 # Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 '''command to display statistics about repository history'''
10 10
11 11 from mercurial.i18n import _
12 12 from mercurial import patch, cmdutil, util, templater
13 13 import sys, os
14 14 import time, datetime
15 15
16 16 def maketemplater(ui, repo, tmpl):
17 17 tmpl = templater.parsestring(tmpl, quoted=False)
18 18 try:
19 19 t = cmdutil.changeset_templater(ui, repo, False, None, None, False)
20 20 except SyntaxError, inst:
21 21 raise util.Abort(inst.args[0])
22 22 t.use_template(tmpl)
23 23 return t
24 24
25 25 def changedlines(ui, repo, ctx1, ctx2, fns):
26 26 added, removed = 0, 0
27 27 fmatch = cmdutil.matchfiles(repo, fns)
28 28 diff = ''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
29 29 for l in diff.split('\n'):
30 30 if l.startswith("+") and not l.startswith("+++ "):
31 31 added += 1
32 32 elif l.startswith("-") and not l.startswith("--- "):
33 33 removed += 1
34 34 return (added, removed)
35 35
36 36 def countrate(ui, repo, amap, *pats, **opts):
37 37 """Calculate stats"""
38 38 if opts.get('dateformat'):
39 39 def getkey(ctx):
40 40 t, tz = ctx.date()
41 41 date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
42 42 return date.strftime(opts['dateformat'])
43 43 else:
44 44 tmpl = opts.get('template', '{author|email}')
45 45 tmpl = maketemplater(ui, repo, tmpl)
46 46 def getkey(ctx):
47 47 ui.pushbuffer()
48 48 tmpl.show(ctx)
49 49 return ui.popbuffer()
50 50
51 state = {'count': 0, 'pct': 0}
51 state = {'count': 0}
52 52 rate = {}
53 53 df = False
54 54 if opts.get('date'):
55 55 df = util.matchdate(opts['date'])
56 56
57 57 m = cmdutil.match(repo, pats, opts)
58 58 def prep(ctx, fns):
59 59 rev = ctx.rev()
60 60 if df and not df(ctx.date()[0]): # doesn't match date format
61 61 return
62 62
63 63 key = getkey(ctx)
64 64 key = amap.get(key, key) # alias remap
65 65 if opts.get('changesets'):
66 66 rate[key] = (rate.get(key, (0,))[0] + 1, 0)
67 67 else:
68 68 parents = ctx.parents()
69 69 if len(parents) > 1:
70 70 ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
71 71 return
72 72
73 73 ctx1 = parents[0]
74 74 lines = changedlines(ui, repo, ctx1, ctx, fns)
75 75 rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
76 76
77 if opts.get('progress'):
78 77 state['count'] += 1
79 newpct = int(100.0 * state['count'] / max(len(repo), 1))
80 if state['pct'] < newpct:
81 state['pct'] = newpct
82 ui.write("\r" + _("generating stats: %d%%") % state['pct'])
83 sys.stdout.flush()
78 ui.progress(_('churning changes'), state['count'], total=len(repo))
84 79
85 80 for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
86 81 continue
87 82
88 if opts.get('progress'):
89 ui.write("\r")
90 sys.stdout.flush()
83 ui.progress(_('churning changes'), None)
91 84
92 85 return rate
93 86
94 87
95 88 def churn(ui, repo, *pats, **opts):
96 89 '''histogram of changes to the repository
97 90
98 91 This command will display a histogram representing the number
99 92 of changed lines or revisions, grouped according to the given
100 93 template. The default template will group changes by author.
101 94 The --dateformat option may be used to group the results by
102 95 date instead.
103 96
104 97 Statistics are based on the number of changed lines, or
105 98 alternatively the number of matching revisions if the
106 99 --changesets option is specified.
107 100
108 101 Examples::
109 102
110 103 # display count of changed lines for every committer
111 104 hg churn -t '{author|email}'
112 105
113 106 # display daily activity graph
114 107 hg churn -f '%H' -s -c
115 108
116 109 # display activity of developers by month
117 110 hg churn -f '%Y-%m' -s -c
118 111
119 112 # display count of lines changed in every year
120 113 hg churn -f '%Y' -s
121 114
122 115 It is possible to map alternate email addresses to a main address
123 116 by providing a file using the following format::
124 117
125 118 <alias email> <actual email>
126 119
127 120 Such a file may be specified with the --aliases option, otherwise
128 121 a .hgchurn file will be looked for in the working directory root.
129 122 '''
130 123 def pad(s, l):
131 124 return (s + " " * l)[:l]
132 125
133 126 amap = {}
134 127 aliases = opts.get('aliases')
135 128 if not aliases and os.path.exists(repo.wjoin('.hgchurn')):
136 129 aliases = repo.wjoin('.hgchurn')
137 130 if aliases:
138 131 for l in open(aliases, "r"):
139 132 l = l.strip()
140 133 alias, actual = l.split()
141 134 amap[alias] = actual
142 135
143 136 rate = countrate(ui, repo, amap, *pats, **opts).items()
144 137 if not rate:
145 138 return
146 139
147 140 sortkey = ((not opts.get('sort')) and (lambda x: -sum(x[1])) or None)
148 141 rate.sort(key=sortkey)
149 142
150 143 # Be careful not to have a zero maxcount (issue833)
151 144 maxcount = float(max(sum(v) for k, v in rate)) or 1.0
152 145 maxname = max(len(k) for k, v in rate)
153 146
154 147 ttywidth = util.termwidth()
155 148 ui.debug("assuming %i character terminal\n" % ttywidth)
156 149 width = ttywidth - maxname - 2 - 2 - 2
157 150
158 151 if opts.get('diffstat'):
159 152 width -= 15
160 153 def format(name, (added, removed)):
161 154 return "%s %15s %s%s\n" % (pad(name, maxname),
162 155 '+%d/-%d' % (added, removed),
163 156 '+' * charnum(added),
164 157 '-' * charnum(removed))
165 158 else:
166 159 width -= 6
167 160 def format(name, count):
168 161 return "%s %6d %s\n" % (pad(name, maxname), sum(count),
169 162 '*' * charnum(sum(count)))
170 163
171 164 def charnum(count):
172 165 return int(round(count * width / maxcount))
173 166
174 167 for name, count in rate:
175 168 ui.write(format(name, count))
176 169
177 170
178 171 cmdtable = {
179 172 "churn":
180 173 (churn,
181 174 [('r', 'rev', [], _('count rate for the specified revision or range')),
182 175 ('d', 'date', '', _('count rate for revisions matching date spec')),
183 176 ('t', 'template', '{author|email}',
184 177 _('template to group changesets')),
185 178 ('f', 'dateformat', '',
186 179 _('strftime-compatible format for grouping by date')),
187 180 ('c', 'changesets', False, _('count rate by number of changesets')),
188 181 ('s', 'sort', False, _('sort by key (default: sort by count)')),
189 182 ('', 'diffstat', False, _('display added/removed lines separately')),
190 183 ('', 'aliases', '', _('file with email aliases')),
191 ('', 'progress', None, _('show progress'))],
192 _("hg churn [-d DATE] [-r REV] [--aliases FILE] [--progress] [FILE]")),
184 ],
185 _("hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]")),
193 186 }
General Comments 0
You need to be logged in to leave comments. Login now