hgext/churn.py
author Simon Sapin <simon.sapin@octobus.net>
Fri, 15 Oct 2021 16:12:00 +0200
changeset 48250 1730b2fceaa1
parent 46430 b84c3d43ff2e
child 48875 6000f5b25c9b
permissions -rw-r--r--
dirstate-v2: adds a flag to mark a file as modified Right now, a files with a file system state that requires a lookup (same size, different mtime) will requires a lookup. If the result of that lookup is a modified files, it will remains ambiguous, requiring a lookup on the next status run too. To fix this, we introduce a dedicated flag in the new format. Such flag will allow to record such file as "known modified" avoiding an extra lookup later. As None of the associate code currently exist in the status code, we do the minimal implementation: if we read a dirstate entry with this flag set, we make it as "ambiguous" so that the next status code has to look it up. The same as it would have to without this flag existing anyway. Differential Revision: https://phab.mercurial-scm.org/D11681
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
     1
# churn.py - create a graph of revisions count grouped by template
3040
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>
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
     4
# Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
     5
#
8225
46293a0c7e9f updated license to be explicit about GPL version 2
Martin Geisler <mg@lazybytes.net>
parents: 8085
diff changeset
     6
# This software may be used and distributed according to the terms of the
10263
25e572394f5c Update license to GPLv2+
Matt Mackall <mpm@selenic.com>
parents: 9672
diff changeset
     7
# GNU General Public License version 2 or any later version.
8228
eee2319c5895 add blank line after copyright notices and after header
Martin Geisler <mg@lazybytes.net>
parents: 8225
diff changeset
     8
8934
9dda4c73fc3b extensions: change descriptions for extensions providing a few commands
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8894
diff changeset
     9
'''command to display statistics about repository history'''
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    10
40241
81e4f039a0cd churn: use integer division consistently
Augie Fackler <augie@google.com>
parents: 40240
diff changeset
    11
from __future__ import absolute_import, division
28094
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    12
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    13
import datetime
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    14
import os
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    15
import time
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    16
7051
5f201f711932 i18n, churn: mark string for translation
Martin Geisler <mg@daimi.au.dk>
parents: 6955
diff changeset
    17
from mercurial.i18n import _
43085
eef9a2d67051 py3: manually import pycompat.open into files that need it
Gregory Szorc <gregory.szorc@gmail.com>
parents: 43077
diff changeset
    18
from mercurial.pycompat import open
28094
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    19
from mercurial import (
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    20
    cmdutil,
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    21
    encoding,
35888
c8e2d6ed1f9e cmdutil: drop aliases for logcmdutil functions (API)
Yuya Nishihara <yuya@tcha.org>
parents: 34974
diff changeset
    22
    logcmdutil,
28094
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    23
    patch,
34974
26ed66ab1e72 py3: handle keyword arguments in hgext/churn.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32837
diff changeset
    24
    pycompat,
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32198
diff changeset
    25
    registrar,
45720
508dfd1c18df scmutil: move walkchangerevs() from cmdutil
Yuya Nishihara <yuya@tcha.org>
parents: 45652
diff changeset
    26
    scmutil,
28094
79fc627578ac churn: use absolute_import
Gregory Szorc <gregory.szorc@gmail.com>
parents: 26587
diff changeset
    27
)
4955
9bbc0217209b churn: get current terminal width if possible
Christian Ebert <blacktrash@gmx.net>
parents: 3963
diff changeset
    28
21245
75c8720092ba churn: declare command using decorator
Gregory Szorc <gregory.szorc@gmail.com>
parents: 21163
diff changeset
    29
cmdtable = {}
32337
46ba2cdda476 registrar: move cmdutil.command to registrar module (API)
Yuya Nishihara <yuya@tcha.org>
parents: 32198
diff changeset
    30
command = registrar.command(cmdtable)
29841
d5883fd055c6 extensions: change magic "shipped with hg" string
Augie Fackler <augie@google.com>
parents: 28628
diff changeset
    31
# Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
25186
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24987
diff changeset
    32
# extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24987
diff changeset
    33
# be specifying the version(s) of Mercurial they are tested with, or
80c5b2666a96 extensions: document that `testedwith = 'internal'` is special
Augie Fackler <augie@google.com>
parents: 24987
diff changeset
    34
# leave the attribute unspecified.
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    35
testedwith = b'ships-with-hg-core'
16743
38caf405d010 hgext: mark all first-party extensions as such
Augie Fackler <raf@durin42.com>
parents: 16231
diff changeset
    36
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    37
45648
3a024d7cd08e cmdutil: make walkchangerevs() call prepare with matcher instead of filenames
Yuya Nishihara <yuya@tcha.org>
parents: 45475
diff changeset
    38
def changedlines(ui, repo, ctx1, ctx2, fmatch):
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
    39
    added, removed = 0, 0
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    40
    diff = b''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
46430
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    41
    inhunk = False
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    42
    for l in diff.split(b'\n'):
46430
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    43
        if inhunk and l.startswith(b"+"):
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
    44
            added += 1
46430
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    45
        elif inhunk and l.startswith(b"-"):
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
    46
            removed += 1
46430
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    47
        elif l.startswith(b"@"):
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    48
            inhunk = True
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    49
        elif l.startswith(b"d"):
b84c3d43ff2e churn: count lines that look like diff headers but are not
Aay Jay Chan <aayjaychan@itopia.com.hk>
parents: 45942
diff changeset
    50
            inhunk = False
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
    51
    return (added, removed)
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
    52
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    53
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    54
def countrate(ui, repo, amap, *pats, **opts):
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    55
    """Calculate stats"""
34974
26ed66ab1e72 py3: handle keyword arguments in hgext/churn.py
Pulkit Goyal <7895pulkit@gmail.com>
parents: 32837
diff changeset
    56
    opts = pycompat.byteskwargs(opts)
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    57
    if opts.get(b'dateformat'):
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    58
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    59
        def getkey(ctx):
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    60
            t, tz = ctx.date()
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    61
            date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
40240
6f3e733848ae churn: fix stack traces on Python 3
Augie Fackler <augie@google.com>
parents: 38401
diff changeset
    62
            return encoding.strtolocal(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    63
                date.strftime(encoding.strfromlocal(opts[b'dateformat']))
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    64
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    65
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    66
    else:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    67
        tmpl = opts.get(b'oldtemplate') or opts.get(b'template')
35888
c8e2d6ed1f9e cmdutil: drop aliases for logcmdutil functions (API)
Yuya Nishihara <yuya@tcha.org>
parents: 34974
diff changeset
    68
        tmpl = logcmdutil.maketemplater(ui, repo, tmpl)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    69
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    70
        def getkey(ctx):
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    71
            ui.pushbuffer()
7369
87158be081b8 cmdutil: use change contexts for cset-printer and cset-templater
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 7308
diff changeset
    72
            tmpl.show(ctx)
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    73
            return ui.popbuffer()
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    74
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    75
    progress = ui.makeprogress(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    76
        _(b'analyzing'), unit=_(b'revisions'), total=len(repo)
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    77
    )
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    78
    rate = {}
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    79
45648
3a024d7cd08e cmdutil: make walkchangerevs() call prepare with matcher instead of filenames
Yuya Nishihara <yuya@tcha.org>
parents: 45475
diff changeset
    80
    def prep(ctx, fmatch):
9654
96fe91be9c1e walkchangerevs: yield contexts
Matt Mackall <mpm@selenic.com>
parents: 9652
diff changeset
    81
        rev = ctx.rev()
14040
9d2be7e17fc1 churn: strip key earlier to avoid false negative seach in aliases
Alexander Solovyov <alexander@solovyov.net>
parents: 13123
diff changeset
    82
        key = getkey(ctx).strip()
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
    83
        key = amap.get(key, key)  # alias remap
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    84
        if opts.get(b'changesets'):
9670
7d56b6ffef72 churn: fix changeset count (broken by 9b127e888640)
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9669
diff changeset
    85
            rate[key] = (rate.get(key, (0,))[0] + 1, 0)
7070
2627ef59195d churn and stats commands merged
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7065
diff changeset
    86
        else:
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    87
            parents = ctx.parents()
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    88
            if len(parents) > 1:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
    89
                ui.note(_(b'revision %d is a merge, ignoring...\n') % (rev,))
9662
f3d60543924f walkchangerevs: move 'add' to callback
Matt Mackall <mpm@selenic.com>
parents: 9655
diff changeset
    90
                return
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    91
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
    92
            ctx1 = parents[0]
45648
3a024d7cd08e cmdutil: make walkchangerevs() call prepare with matcher instead of filenames
Yuya Nishihara <yuya@tcha.org>
parents: 45475
diff changeset
    93
            lines = changedlines(ui, repo, ctx1, ctx, fmatch)
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
    94
            rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
    95
38401
5c0f06a8b497 churn: use progess helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38124
diff changeset
    96
        progress.increment()
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
    97
45650
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
    98
    wopts = logcmdutil.walkopts(
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
    99
        pats=pats,
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
   100
        opts=opts,
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
   101
        revspec=opts[b'rev'],
45652
d1759b2e1888 churn: leverage logcmdutil to filter revisions by --date
Yuya Nishihara <yuya@tcha.org>
parents: 45650
diff changeset
   102
        date=opts[b'date'],
45650
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
   103
        include_pats=opts[b'include'],
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
   104
        exclude_pats=opts[b'exclude'],
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
   105
    )
0356b41fe01d cmdutil: rewrite walkchangerevs() by using logcmdutil functions
Yuya Nishihara <yuya@tcha.org>
parents: 45648
diff changeset
   106
    revs, makefilematcher = logcmdutil.makewalker(repo, wopts)
45720
508dfd1c18df scmutil: move walkchangerevs() from cmdutil
Yuya Nishihara <yuya@tcha.org>
parents: 45652
diff changeset
   107
    for ctx in scmutil.walkchangerevs(repo, revs, makefilematcher, prep):
9662
f3d60543924f walkchangerevs: move 'add' to callback
Matt Mackall <mpm@selenic.com>
parents: 9655
diff changeset
   108
        continue
f3d60543924f walkchangerevs: move 'add' to callback
Matt Mackall <mpm@selenic.com>
parents: 9655
diff changeset
   109
38401
5c0f06a8b497 churn: use progess helper
Martin von Zweigbergk <martinvonz@google.com>
parents: 38124
diff changeset
   110
    progress.complete()
3050
dd1a142988d3 [churn] progress meter
Josef "Jeff" Sipek <jeffpc@josefsipek.net>
parents: 3049
diff changeset
   111
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   112
    return rate
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   113
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   114
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   115
@command(
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   116
    b'churn',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   117
    [
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   118
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   119
            b'r',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   120
            b'rev',
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   121
            [],
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   122
            _(b'count rate for the specified revision or revset'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   123
            _(b'REV'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   124
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   125
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   126
            b'd',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   127
            b'date',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   128
            b'',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   129
            _(b'count rate for revisions matching date spec'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   130
            _(b'DATE'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   131
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   132
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   133
            b't',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   134
            b'oldtemplate',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   135
            b'',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   136
            _(b'template to group changesets (DEPRECATED)'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   137
            _(b'TEMPLATE'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   138
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   139
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   140
            b'T',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   141
            b'template',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   142
            b'{author|email}',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   143
            _(b'template to group changesets'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   144
            _(b'TEMPLATE'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   145
        ),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   146
        (
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   147
            b'f',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   148
            b'dateformat',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   149
            b'',
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   150
            _(b'strftime-compatible format for grouping by date'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   151
            _(b'FORMAT'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   152
        ),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   153
        (b'c', b'changesets', False, _(b'count rate by number of changesets')),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   154
        (b's', b'sort', False, _(b'sort by key (default: sort by count)')),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   155
        (b'', b'diffstat', False, _(b'display added/removed lines separately')),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   156
        (b'', b'aliases', b'', _(b'file with email aliases'), _(b'FILE')),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   157
    ]
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   158
    + cmdutil.walkopts,
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   159
    _(b"hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]"),
40293
c303d65d2e34 help: assigning categories to existing commands
rdamazio@google.com
parents: 40264
diff changeset
   160
    helpcategory=command.CATEGORY_MAINTENANCE,
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   161
    inferrepo=True,
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   162
)
7070
2627ef59195d churn and stats commands merged
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7065
diff changeset
   163
def churn(ui, repo, *pats, **opts):
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45720
diff changeset
   164
    """histogram of changes to the repository
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   165
8823
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   166
    This command will display a histogram representing the number
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   167
    of changed lines or revisions, grouped according to the given
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   168
    template. The default template will group changes by author.
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   169
    The --dateformat option may be used to group the results by
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   170
    date instead.
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   171
8823
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   172
    Statistics are based on the number of changed lines, or
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   173
    alternatively the number of matching revisions if the
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   174
    --changesets option is specified.
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   175
9205
83132980e9cd churn: use reST syntax for literal blocks
Martin Geisler <mg@lazybytes.net>
parents: 9056
diff changeset
   176
    Examples::
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6598
diff changeset
   177
7070
2627ef59195d churn and stats commands merged
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7065
diff changeset
   178
      # display count of changed lines for every committer
32198
a0e46f6b248b churn: use the non-deprecated template option in the examples
Matt Harbison <matt_harbison@yahoo.com>
parents: 29841
diff changeset
   179
      hg churn -T "{author|email}"
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   180
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   181
      # display daily activity graph
19959
9ef92384415c doc: use double quotation mark to quote arguments in examples for Windows users
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19464
diff changeset
   182
      hg churn -f "%H" -s -c
6666
53465a7464e2 convert comments to docstrings in a bunch of extensions
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 6598
diff changeset
   183
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   184
      # display activity of developers by month
19959
9ef92384415c doc: use double quotation mark to quote arguments in examples for Windows users
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19464
diff changeset
   185
      hg churn -f "%Y-%m" -s -c
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
   186
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   187
      # display count of lines changed in every year
19959
9ef92384415c doc: use double quotation mark to quote arguments in examples for Windows users
FUJIWARA Katsunori <foozy@lares.dti.ne.jp>
parents: 19464
diff changeset
   188
      hg churn -f "%Y" -s
7070
2627ef59195d churn and stats commands merged
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7065
diff changeset
   189
45475
0d119802242b churn: add an usage example in docstring
"Stephane" <stephane@yaal.fr>
parents: 43506
diff changeset
   190
      # display count of lines changed in a time range
0d119802242b churn: add an usage example in docstring
"Stephane" <stephane@yaal.fr>
parents: 43506
diff changeset
   191
      hg churn -d "2020-04 to 2020-09"
0d119802242b churn: add an usage example in docstring
"Stephane" <stephane@yaal.fr>
parents: 43506
diff changeset
   192
8823
d9f4c182aeca churn: improve description
Cédric Duval <cedricduval@free.fr>
parents: 8254
diff changeset
   193
    It is possible to map alternate email addresses to a main address
9254
db13255617b3 churn: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9205
diff changeset
   194
    by providing a file using the following format::
8843
eb7b247a98ea kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 8823
diff changeset
   195
11264
30c620e48d1c churn: support spaces in aliases (issue2222)
Alexander Solovyov <piranha@piranha.org.ua>
parents: 10905
diff changeset
   196
      <alias email> = <actual email>
8254
f108e89400d8 churn: use .hgchurn in repo root as default map file
Martin Geisler <mg@lazybytes.net>
parents: 8228
diff changeset
   197
9254
db13255617b3 churn: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9205
diff changeset
   198
    Such a file may be specified with the --aliases option, otherwise
db13255617b3 churn: wrap docstrings at 70 characters
Martin Geisler <mg@lazybytes.net>
parents: 9205
diff changeset
   199
    a .hgchurn file will be looked for in the working directory root.
19464
68f7129af6a8 churn: split email aliases from the right
Matthew Turk <matthewturk@gmail.com>
parents: 18369
diff changeset
   200
    Aliases will be split from the rightmost "=".
45942
89a2afe31e82 formating: upgrade to black 20.8b1
Augie Fackler <raf@durin42.com>
parents: 45720
diff changeset
   201
    """
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   202
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   203
    def pad(s, l):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   204
        return s + b" " * (l - encoding.colwidth(s))
3223
53e843840349 Whitespace/Tab cleanup
Thomas Arendsen Hein <thomas@intevation.de>
parents: 3090
diff changeset
   205
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   206
    amap = {}
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43085
diff changeset
   207
    aliases = opts.get('aliases')
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   208
    if not aliases and os.path.exists(repo.wjoin(b'.hgchurn')):
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   209
        aliases = repo.wjoin(b'.hgchurn')
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   210
    if aliases:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   211
        for l in open(aliases, b"rb"):
12069
7c3c44413bc1 churn: do not crash on malformed lines in alias file
Martin Geisler <mg@lazybytes.net>
parents: 12068
diff changeset
   212
            try:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   213
                alias, actual = l.rsplit(b'=' in l and b'=' or None, 1)
12069
7c3c44413bc1 churn: do not crash on malformed lines in alias file
Martin Geisler <mg@lazybytes.net>
parents: 12068
diff changeset
   214
                amap[alias.strip()] = actual.strip()
7c3c44413bc1 churn: do not crash on malformed lines in alias file
Martin Geisler <mg@lazybytes.net>
parents: 12068
diff changeset
   215
            except ValueError:
7c3c44413bc1 churn: do not crash on malformed lines in alias file
Martin Geisler <mg@lazybytes.net>
parents: 12068
diff changeset
   216
                l = l.strip()
7c3c44413bc1 churn: do not crash on malformed lines in alias file
Martin Geisler <mg@lazybytes.net>
parents: 12068
diff changeset
   217
                if l:
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   218
                    ui.warn(_(b"skipping malformed alias: %s\n") % l)
12068
2e7647d25458 churn: do not crash on empty lines in alias file
Ronny Pfannschmidt <Ronny.Pfannschmidt@gmx.de>
parents: 11321
diff changeset
   219
                continue
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   220
36392
e9bcc2efb7e8 py3: convert dict.items() to list explicitly
Pulkit Goyal <7895pulkit@gmail.com>
parents: 35888
diff changeset
   221
    rate = list(countrate(ui, repo, amap, *pats, **opts).items())
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   222
    if not rate:
5588
083b6e3142a2 churn: avoid division by zero
Matt Mackall <mpm@selenic.com>
parents: 5482
diff changeset
   223
        return
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   224
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43085
diff changeset
   225
    if opts.get('sort'):
18369
2150e70c0ee1 churn: sort users with same churn by name
Mads Kiilerich <mads@kiilerich.com>
parents: 17773
diff changeset
   226
        rate.sort()
2150e70c0ee1 churn: sort users with same churn by name
Mads Kiilerich <mads@kiilerich.com>
parents: 17773
diff changeset
   227
    else:
2150e70c0ee1 churn: sort users with same churn by name
Mads Kiilerich <mads@kiilerich.com>
parents: 17773
diff changeset
   228
        rate.sort(key=lambda x: (-sum(x[1]), x))
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   229
9388
f7968bba2307 churn: issue833 was reintroduced in 9bc46d069a76, correct it and add a test
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 8934
diff changeset
   230
    # Be careful not to have a zero maxcount (issue833)
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   231
    maxcount = float(max(sum(v) for k, v in rate)) or 1.0
9390
637f2726ec7f churn: use genexps now that we dropped 2.3 compatibility
Nicolas Dumazet <nicdumz.commits@gmail.com>
parents: 9389
diff changeset
   232
    maxname = max(len(k) for k, v in rate)
3040
f74077473b36 Churn extension
Josef "Jeff" Sipek <jeff@josefsipek.net>
parents:
diff changeset
   233
12689
c52c629ce19e termwidth: move to ui.ui from util
Augie Fackler <durin42@gmail.com>
parents: 12070
diff changeset
   234
    ttywidth = ui.termwidth()
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   235
    ui.debug(b"assuming %i character terminal\n" % ttywidth)
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   236
    width = ttywidth - maxname - 2 - 2 - 2
7065
9bc46d069a76 churn: generalisation, now it is possible to see statistics grouped by custom template
Alexander Solovyov <piranha@piranha.org.ua>
parents: 7051
diff changeset
   237
43506
9f70512ae2cf cleanup: remove pointless r-prefixes on single-quoted strings
Augie Fackler <augie@google.com>
parents: 43085
diff changeset
   238
    if opts.get('diffstat'):
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   239
        width -= 15
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   240
11501
deb5d02ae91c churn: remove tuple parameter unpacking (deprecated in py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11321
diff changeset
   241
        def format(name, diffstat):
deb5d02ae91c churn: remove tuple parameter unpacking (deprecated in py3k)
Renato Cunha <renatoc@gmail.com>
parents: 11321
diff changeset
   242
            added, removed = diffstat
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   243
            return b"%s %15s %s%s\n" % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   244
                pad(name, maxname),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   245
                b'+%d/-%d' % (added, removed),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   246
                ui.label(b'+' * charnum(added), b'diffstat.inserted'),
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   247
                ui.label(b'-' * charnum(removed), b'diffstat.deleted'),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   248
            )
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   249
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   250
    else:
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   251
        width -= 6
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   252
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   253
        def format(name, count):
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   254
            return b"%s %6d %s\n" % (
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   255
                pad(name, maxname),
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   256
                sum(count),
43077
687b865b95ad formatting: byteify all mercurial/ and hgext/ string literals
Augie Fackler <augie@google.com>
parents: 43076
diff changeset
   257
                b'*' * charnum(sum(count)),
43076
2372284d9457 formatting: blacken the codebase
Augie Fackler <augie@google.com>
parents: 40293
diff changeset
   258
            )
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   259
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   260
    def charnum(count):
40264
12e2e5cd5777 churn: remove redundant round()
Augie Fackler <augie@google.com>
parents: 40241
diff changeset
   261
        return int(count * width // maxcount)
9669
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   262
9b127e888640 churn: ability to display added/removed lines separately
Alexander Solovyov <piranha@piranha.org.ua>
parents: 9665
diff changeset
   263
    for name, count in rate:
11310
ac873ecfc3c2 Backed out changeset: e1dde7363601
Steve Borho <steve@borho.org>
parents: 11302
diff changeset
   264
        ui.write(format(name, count))