##// END OF EJS Templates
fix conflicting variables when no native osutil is available...
fix conflicting variables when no native osutil is available thanks weijun for the bug report and patch, fix issue1309

File last commit:

r7051:5f201f71 default
r7057:094af6ee default
Show More
churn.py
119 lines | 3.5 KiB | text/x-python | PythonLexer
Patrick Mezard
Make churn an official extension
r6348 # churn.py - create a graph showing who changed the most lines
#
# Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Dirkjan Ochtman
convert comments to docstrings in a bunch of extensions
r6666 '''allow graphing the number of lines changed per contributor'''
Patrick Mezard
Make churn an official extension
r6348
Martin Geisler
i18n, churn: mark string for translation
r7051 from mercurial.i18n import _
Matt Mackall
churn: major refactor...
r6759 from mercurial import patch, cmdutil, util, node
Patrick Mezard
Make churn an official extension
r6348 import os, sys
def get_tty_width():
if 'COLUMNS' in os.environ:
try:
return int(os.environ['COLUMNS'])
except ValueError:
pass
try:
import termios, array, fcntl
for dev in (sys.stdout, sys.stdin):
try:
fd = dev.fileno()
if not os.isatty(fd):
continue
arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
return array.array('h', arri)[1]
except ValueError:
pass
except ImportError:
pass
return 80
Matt Mackall
churn: major refactor...
r6759 def countrevs(ui, repo, amap, revs, progress=False):
Patrick Mezard
Make churn an official extension
r6348 stats = {}
Matt Mackall
churn: major refactor...
r6759 count = pct = 0
Patrick Mezard
Make churn an official extension
r6348 if not revs:
Matt Mackall
churn: major refactor...
r6759 revs = range(len(repo))
Patrick Mezard
Make churn an official extension
r6348
for rev in revs:
Matt Mackall
churn: major refactor...
r6759 ctx2 = repo[rev]
parents = ctx2.parents()
if len(parents) > 1:
Patrick Mezard
Make churn an official extension
r6348 ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
continue
Matt Mackall
churn: major refactor...
r6759 ctx1 = parents[0]
lines = 0
ui.pushbuffer()
patch.diff(repo, ctx1.node(), ctx2.node())
diff = ui.popbuffer()
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
churn: major refactor...
r6759 for l in diff.split('\n'):
if (l.startswith("+") and not l.startswith("+++ ") or
l.startswith("-") and not l.startswith("--- ")):
lines += 1
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
churn: major refactor...
r6759 user = util.email(ctx2.user())
user = amap.get(user, user) # remap
stats[user] = stats.get(user, 0) + lines
Martin Geisler
i18n: mark strings for translation in churn extension
r6955 ui.debug(_("rev %d: %d lines by %s\n") % (rev, lines, user))
Patrick Mezard
Make churn an official extension
r6348
if progress:
Matt Mackall
churn: major refactor...
r6759 count += 1
newpct = int(100.0 * count / max(len(revs), 1))
if pct < newpct:
pct = newpct
Martin Geisler
i18n: mark strings for translation in churn extension
r6955 ui.write(_("\rGenerating stats: %d%%") % pct)
Patrick Mezard
Make churn an official extension
r6348 sys.stdout.flush()
if progress:
ui.write("\r")
sys.stdout.flush()
return stats
def churn(ui, repo, **opts):
Dirkjan Ochtman
convert comments to docstrings in a bunch of extensions
r6666 '''graphs the number of lines changed
The map file format used to specify aliases is fairly simple:
<alias email> <actual email>'''
Patrick Mezard
Make churn an official extension
r6348
def pad(s, l):
Matt Mackall
churn: major refactor...
r6759 return (s + " " * l)[:l]
Patrick Mezard
Make churn an official extension
r6348
amap = {}
aliases = opts.get('aliases')
if aliases:
Matt Mackall
churn: major refactor...
r6759 for l in open(aliases, "r"):
l = l.strip()
alias, actual = l.split()
amap[alias] = actual
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
util: add sort helper
r6762 revs = util.sort([int(r) for r in cmdutil.revrange(repo, opts['rev'])])
Matt Mackall
churn: major refactor...
r6759 stats = countrevs(ui, repo, amap, revs, opts.get('progress'))
if not stats:
Patrick Mezard
Make churn an official extension
r6348 return
Matt Mackall
util: add sort helper
r6762 stats = util.sort([(-l, u, l) for u,l in stats.items()])
Matt Mackall
churn: major refactor...
r6759 maxchurn = float(max(1, stats[0][2]))
maxuser = max([len(u) for k, u, l in stats])
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
churn: major refactor...
r6759 ttywidth = get_tty_width()
ui.debug(_("assuming %i character terminal\n") % ttywidth)
width = ttywidth - maxuser - 2 - 6 - 2 - 2
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
churn: major refactor...
r6759 for k, user, churn in stats:
print "%s %6d %s" % (pad(user, maxuser), churn,
"*" * int(churn * width / maxchurn))
Patrick Mezard
Make churn an official extension
r6348
cmdtable = {
"churn":
(churn,
[('r', 'rev', [], _('limit statistics to the specified revisions')),
('', 'aliases', '', _('file with email aliases')),
('', 'progress', None, _('show progress'))],
Martin Geisler
i18n, churn: mark string for translation
r7051 _('hg churn [-r REVISIONS] [--aliases FILE] [--progress]')),
Patrick Mezard
Make churn an official extension
r6348 }