contrib/churn.py
author Alexis S. L. Carvalho <alexis@cecm.usp.br>
Thu, 14 Feb 2008 18:08:16 -0200
changeset 6109 242595e612ed
parent 5990 71d675f4b1f8
child 6212 e75aab656f46
permissions -rw-r--r--
revert: unify forget and remove lists This doesn't make a difference right now, but after the next revision some files in state 'a' may end up in the deleted list, and revert won't be able to just remove all files in that list.
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     1
# churn.py - create a graph showing who changed the most lines
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     2
#
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     3
# Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     4
#
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     5
# This software may be used and distributed according to the terms
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     6
# of the GNU General Public License, incorporated herein by reference.
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     7
#
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     8
#
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     9
# Aliases map file format is simple one alias per line in the following
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    10
# format:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    11
#
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    12
# <alias email> <actual email>
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    13
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
    14
from mercurial.i18n import gettext as _
5976
9f1e6ab76069 templates: move filters to their own module
Matt Mackall <mpm@selenic.com>
parents: 5975
diff changeset
    15
from mercurial import hg, mdiff, cmdutil, ui, util, templatefilters, node
4955
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    16
import os, sys
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    17
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    18
def get_tty_width():
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    19
    if 'COLUMNS' in os.environ:
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    20
        try:
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    21
            return int(os.environ['COLUMNS'])
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    22
        except ValueError:
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    23
            pass
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    24
    try:
5419
041bd297f01e churn: simplify code to get terminal width
Christian Ebert <blacktrash@gmx.net>
parents: 4955
diff changeset
    25
        import termios, array, fcntl
4955
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    26
        for dev in (sys.stdout, sys.stdin):
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    27
            try:
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    28
                fd = dev.fileno()
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    29
                if not os.isatty(fd):
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    30
                    continue
5419
041bd297f01e churn: simplify code to get terminal width
Christian Ebert <blacktrash@gmx.net>
parents: 4955
diff changeset
    31
                arri = fcntl.ioctl(fd, termios.TIOCGWINSZ, '\0' * 8)
041bd297f01e churn: simplify code to get terminal width
Christian Ebert <blacktrash@gmx.net>
parents: 4955
diff changeset
    32
                return array.array('h', arri)[1]
4955
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    33
            except ValueError:
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    34
                pass
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    35
    except ImportError:
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    36
        pass
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    37
    return 80
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    38
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    39
def __gather(ui, repo, node1, node2):
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    40
    def dirtywork(f, mmap1, mmap2):
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    41
        lines = 0
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    42
3042
2d35d7c6f251 [churn] Trivial cleanup suggested by Thomas
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3041
diff changeset
    43
        to = mmap1 and repo.file(f).read(mmap1[f]) or None
2d35d7c6f251 [churn] Trivial cleanup suggested by Thomas
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3041
diff changeset
    44
        tn = mmap2 and repo.file(f).read(mmap2[f]) or None
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    45
5482
e5eedd74e70f Use both the from and to name in mdiff.unidiff.
Dustin Sallings <dustin@spy.net>
parents: 5419
diff changeset
    46
        diff = mdiff.unidiff(to, "", tn, "", f, f).split("\n")
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    47
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    48
        for line in diff:
3043
fe0e3508ec6e [churn] Trivial cleanup
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3042
diff changeset
    49
            if not line:
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    50
                continue # skip EOF
3042
2d35d7c6f251 [churn] Trivial cleanup suggested by Thomas
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3041
diff changeset
    51
            if line.startswith(" "):
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    52
                continue # context line
3042
2d35d7c6f251 [churn] Trivial cleanup suggested by Thomas
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3041
diff changeset
    53
            if line.startswith("--- ") or line.startswith("+++ "):
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    54
                continue # begining of diff
3042
2d35d7c6f251 [churn] Trivial cleanup suggested by Thomas
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3041
diff changeset
    55
            if line.startswith("@@ "):
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    56
                continue # info line
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    57
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    58
            # changed lines
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    59
            lines += 1
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    60
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    61
        return lines
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    62
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    63
    ##
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    64
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    65
    lines = 0
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    66
3048
8d344bc72e68 [churn] repo.changes was renamed to repo.status
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3046
diff changeset
    67
    changes = repo.status(node1, node2, None, util.always)[:5]
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    68
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    69
    modified, added, removed, deleted, unknown = changes
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    70
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    71
    who = repo.changelog.read(node2)[1]
5975
75d9fe70c654 templater: move email function to util
Matt Mackall <mpm@selenic.com>
parents: 5915
diff changeset
    72
    who = util.email(who) # get the email of the person
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    73
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    74
    mmap1 = repo.manifest.read(repo.changelog.read(node1)[0])
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    75
    mmap2 = repo.manifest.read(repo.changelog.read(node2)[0])
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    76
    for f in modified:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    77
        lines += dirtywork(f, mmap1, mmap2)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    78
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    79
    for f in added:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    80
        lines += dirtywork(f, None, mmap2)
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
    81
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    82
    for f in removed:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    83
        lines += dirtywork(f, mmap1, None)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    84
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    85
    for f in deleted:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    86
        lines += dirtywork(f, mmap1, mmap2)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    87
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    88
    for f in unknown:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    89
        lines += dirtywork(f, mmap1, mmap2)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    90
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    91
    return (who, lines)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    92
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
    93
def gather_stats(ui, repo, amap, revs=None, progress=False):
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    94
    stats = {}
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
    95
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    96
    cl    = repo.changelog
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    97
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
    98
    if not revs:
3046
2a4d4aecb2b4 Merge with Brendan Cully
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents: 3045 3044
diff changeset
    99
        revs = range(0, cl.count())
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   100
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   101
    nr_revs = len(revs)
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   102
    cur_rev = 0
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   103
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   104
    for rev in revs:
3051
7ffaf5aba4d8 [churn] Fix progress bar not incrementing when merge cset is encountered
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3050
diff changeset
   105
        cur_rev += 1 # next revision
7ffaf5aba4d8 [churn] Fix progress bar not incrementing when merge cset is encountered
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3050
diff changeset
   106
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   107
        node2    = cl.node(rev)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   108
        node1    = cl.parents(node2)[0]
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   109
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   110
        if cl.parents(node2)[1] != node.nullid:
3049
461573aa02ef [churn] Ignore merge csets
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3048
diff changeset
   111
            ui.note(_('Revision %d is a merge, ignoring...\n') % (rev,))
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   112
            continue
3049
461573aa02ef [churn] Ignore merge csets
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3048
diff changeset
   113
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   114
        who, lines = __gather(ui, repo, node1, node2)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   115
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   116
        # remap the owner if possible
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5588
diff changeset
   117
        if who in amap:
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   118
            ui.note("using '%s' alias for '%s'\n" % (amap[who], who))
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   119
            who = amap[who]
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   120
5915
d0576d065993 Prefer i in d over d.has_key(i)
Christian Ebert <blacktrash@gmx.net>
parents: 5588
diff changeset
   121
        if not who in stats:
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   122
            stats[who] = 0
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   123
        stats[who] += lines
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   124
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   125
        ui.note("rev %d: %d lines by %s\n" % (rev, lines, who))
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   126
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   127
        if progress:
5588
083b6e3142a2 churn: avoid division by zero
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
   128
            nr_revs = max(nr_revs, 1)
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   129
            if int(100.0*(cur_rev - 1)/nr_revs) < int(100.0*cur_rev/nr_revs):
5990
71d675f4b1f8 Fixed typo: Gnerating -> Generating
Thomas Arendsen Hein <thomas@intevation.de>
parents: 5989
diff changeset
   130
                ui.write("\rGenerating stats: %d%%" % (int(100.0*cur_rev/nr_revs),))
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   131
                sys.stdout.flush()
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   132
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   133
    if progress:
5989
a7817ad608ea added \r for progress counting in churn extension
Armin Ronacher <armin.ronacher@active-4.com>
parents: 5976
diff changeset
   134
        ui.write("\r")
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   135
        sys.stdout.flush()
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   136
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   137
    return stats
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   138
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   139
def churn(ui, repo, **opts):
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   140
    "Graphs the number of lines changed"
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
   141
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   142
    def pad(s, l):
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   143
        if len(s) < l:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   144
            return s + " " * (l-len(s))
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   145
        return s[0:l]
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   146
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   147
    def graph(n, maximum, width, char):
5588
083b6e3142a2 churn: avoid division by zero
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
   148
        maximum = max(1, maximum)
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   149
        n = int(n * width / float(maximum))
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
   150
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   151
        return char * (n)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   152
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   153
    def get_aliases(f):
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   154
        aliases = {}
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   155
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   156
        for l in f.readlines():
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   157
            l = l.strip()
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   158
            alias, actual = l.split(" ")
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   159
            aliases[alias] = actual
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   160
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   161
        return aliases
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
   162
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   163
    amap = {}
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   164
    aliases = opts.get('aliases')
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   165
    if aliases:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   166
        try:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   167
            f = open(aliases,"r")
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   168
        except OSError, e:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   169
            print "Error: " + e
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   170
            return
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   171
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   172
        amap = get_aliases(f)
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   173
        f.close()
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   174
3792
4670470b97bd Fix revrange() call in the churn contrib
Edouard Gomez <ed.gomez@free.fr>
parents: 3223
diff changeset
   175
    revs = [int(r) for r in cmdutil.revrange(repo, opts['rev'])]
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   176
    revs.sort()
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   177
    stats = gather_stats(ui, repo, amap, revs, opts.get('progress'))
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   178
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   179
    # make a list of tuples (name, lines) and sort it in descending order
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   180
    ordered = stats.items()
3060
50e0392d51df Fix for Python 2.3 compatibility.
Shun-ichi GOTO <shunichi.goto@gmail.com>
parents: 3052
diff changeset
   181
    ordered.sort(lambda x, y: cmp(y[1], x[1]))
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   182
5588
083b6e3142a2 churn: avoid division by zero
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
   183
    if not ordered:
083b6e3142a2 churn: avoid division by zero
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
   184
        return
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   185
    maximum = ordered[0][1]
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   186
4955
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
   187
    width = get_tty_width()
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
   188
    ui.note(_("assuming %i character terminal\n") % width)
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
   189
    width -= 1
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   190
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   191
    for i in ordered:
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   192
        person = i[0]
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   193
        lines = i[1]
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   194
        print "%s %6d %s" % (pad(person, 20), lines,
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   195
                graph(lines, maximum, width - 20 - 1 - 6 - 2 - 2, '*'))
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   196
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   197
cmdtable = {
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   198
    "churn":
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   199
    (churn,
3045
c0be8990e819 Add revision range support
Brendan Cully <brendan@kublai.com>
parents: 3043
diff changeset
   200
     [('r', 'rev', [], _('limit statistics to the specified revisions')),
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   201
      ('', 'aliases', '', _('file with email aliases')),
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   202
      ('', 'progress', None, _('show progress'))],
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   203
    'hg churn [-r revision range] [-a file] [--progress]'),
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   204
}