##// END OF EJS Templates
pathcopies: give up any optimization based on `introrev`...
pathcopies: give up any optimization based on `introrev` Between 8a0136f69027 and d98fb3f42f33, we sped up the search for the introduction revision during path copies. However, further checking show that finding the introduction revision is still expensive and that we are better off without it. So we simply drop it and only rely on the linkrev optimisation. I ran `perfpathcopies` on 6989 pair of revision in the pypy repository (`hg perfhelper-pathcopies`. The result is massively in favor of dropping this condition. The result of the copy tracing are unchanged. Attempt to use a smaller changes preserving linkrev usage were unsuccessful, it can return wrong result. The following changesets broke test-mv-cp-st-diff.t - if not f.isintroducedafter(limit): + if limit >= 0 and f.linkrev() < limit: return None Here are various numbers (before this changeset/after this changesets) source destination before after saved-time ratio worth cases e66f24650daf 695dfb0f493b 1.062843 1.246369 -0.183526 1.172675 c979853a3b6a 8d60fe293e79 1.036985 1.196414 -0.159429 1.153743 22349fa2fc33 fbb1c9fd86c0 0.879926 1.038682 -0.158756 1.180420 682b98f3e672 a4878080a536 0.909952 1.063801 -0.153849 1.169074 5adabc9b9848 920958a93997 0.993622 1.147452 -0.153830 1.154817 worse 1% dbfbfcf077e9 aea8f2fd3593 1.016595 1.082999 -0.066404 1.065320 worse 5% c95f1ced15f2 7d29d5e39734 0.453694 0.471156 -0.017462 1.038488 worse 10% 3e144ed1d5b7 2aef0e942480 0.035140 0.037535 -0.002395 1.068156 worse 25% 321fc60db035 801748ba582a 0.009267 0.009325 -0.000058 1.006259 median 2088ce763fc2 e6991321d78b 0.000665 0.000651 0.000014 0.978947 best 25% 915631a97de6 385b31354be6 0.040743 0.040363 0.000380 0.990673 best 10% ad495c36a765 19c10384d3e7 0.431658 0.411490 0.020168 0.953278 best 5% d13ae7d283ae 813c99f810ac 1.141404 1.075346 0.066058 0.942126 best 1% 81593cb4a496 99ae11866969 1.833297 0.063823 1.769474 0.034813 best cases c3b14617fbd7 743a0fcaa4eb 1101.811740 2.735970 1099.075770 0.002483 c3b14617fbd7 9ba6ab77fd29 1116.753953 2.800729 1113.953224 0.002508 058b99d6e81f 57e249b7a3ea 1246.128485 3.042762 1243.085723 0.002442 9a8c361aab49 0354a250d371 1253.111894 3.085796 1250.026098 0.002463 442dbbc53c68 3ec1002a818c 1261.786294 3.138607 1258.647687 0.002487 As one can see, the average case is not really impacted. However, the worth case we get after this changeset are much better than the one we had before it. We have 30 pairs where improvements are above 10 minutes. This reflect in the combined time for all pairs before: 26256s after: 1300s (-95%) If we remove these pathological 30 cases, we still see a significant improvements: before: 1631s after: 1245s (-24%)

File last commit:

r43355:eef9a2d6 default
r43469:c16fe77e default
Show More
churn.py
257 lines | 7.4 KiB | text/x-python | PythonLexer
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # churn.py - create a graph of revisions count grouped by template
Patrick Mezard
Make churn an official extension
r6348 #
# Copyright 2006 Josef "Jeff" Sipek <jeffpc@josefsipek.net>
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # Copyright 2008 Alexander Solovyov <piranha@piranha.org.ua>
Patrick Mezard
Make churn an official extension
r6348 #
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Martin Geisler
add blank line after copyright notices and after header
r8228
Dirkjan Ochtman
extensions: change descriptions for extensions providing a few commands
r8934 '''command to display statistics about repository history'''
Patrick Mezard
Make churn an official extension
r6348
Augie Fackler
churn: use integer division consistently...
r40277 from __future__ import absolute_import, division
Gregory Szorc
churn: use absolute_import
r28094
import datetime
import os
import time
Martin Geisler
i18n, churn: mark string for translation
r7051 from mercurial.i18n import _
Gregory Szorc
py3: manually import pycompat.open into files that need it...
r43355 from mercurial.pycompat import open
Gregory Szorc
churn: use absolute_import
r28094 from mercurial import (
cmdutil,
encoding,
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 logcmdutil,
Gregory Szorc
churn: use absolute_import
r28094 patch,
Pulkit Goyal
py3: handle keyword arguments in hgext/churn.py...
r34975 pycompat,
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 registrar,
Gregory Szorc
churn: use absolute_import
r28094 scmutil,
)
Boris Feld
util: extract all date-related utils in utils/dateutil module...
r36625 from mercurial.utils import dateutil
Patrick Mezard
Make churn an official extension
r6348
Gregory Szorc
churn: declare command using decorator
r21245 cmdtable = {}
Yuya Nishihara
registrar: move cmdutil.command to registrar module (API)...
r32337 command = registrar.command(cmdtable)
Augie Fackler
extensions: change magic "shipped with hg" string...
r29841 # Note for extension authors: ONLY specify testedwith = 'ships-with-hg-core' for
Augie Fackler
extensions: document that `testedwith = 'internal'` is special...
r25186 # extensions which SHIP WITH MERCURIAL. Non-mainline extensions should
# be specifying the version(s) of Mercurial they are tested with, or
# leave the attribute unspecified.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 testedwith = b'ships-with-hg-core'
Augie Fackler
hgext: mark all first-party extensions as such
r16743
Augie Fackler
formatting: blacken the codebase...
r43346
madhu@madhu
Returns lines changed for paths specified as arguments correctly....
r7870 def changedlines(ui, repo, ctx1, ctx2, fns):
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 added, removed = 0, 0
Matt Mackall
scmutil: drop aliases in cmdutil for match functions
r14322 fmatch = scmutil.matchfiles(repo, fns)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 diff = b''.join(patch.diff(repo, ctx1.node(), ctx2.node(), fmatch))
for l in diff.split(b'\n'):
if l.startswith(b"+") and not l.startswith(b"+++ "):
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 added += 1
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 elif l.startswith(b"-") and not l.startswith(b"--- "):
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 removed += 1
return (added, removed)
Patrick Mezard
Make churn an official extension
r6348
Augie Fackler
formatting: blacken the codebase...
r43346
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 def countrate(ui, repo, amap, *pats, **opts):
"""Calculate stats"""
Pulkit Goyal
py3: handle keyword arguments in hgext/churn.py...
r34975 opts = pycompat.byteskwargs(opts)
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'dateformat'):
Augie Fackler
formatting: blacken the codebase...
r43346
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 def getkey(ctx):
t, tz = ctx.date()
date = datetime.datetime(*time.gmtime(float(t) - tz)[:6])
Augie Fackler
churn: fix stack traces on Python 3...
r40276 return encoding.strtolocal(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 date.strftime(encoding.strfromlocal(opts[b'dateformat']))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 else:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmpl = opts.get(b'oldtemplate') or opts.get(b'template')
Yuya Nishihara
cmdutil: drop aliases for logcmdutil functions (API)...
r35906 tmpl = logcmdutil.maketemplater(ui, repo, tmpl)
Augie Fackler
formatting: blacken the codebase...
r43346
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 def getkey(ctx):
ui.pushbuffer()
Dirkjan Ochtman
cmdutil: use change contexts for cset-printer and cset-templater
r7369 tmpl.show(ctx)
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 return ui.popbuffer()
Augie Fackler
formatting: blacken the codebase...
r43346 progress = ui.makeprogress(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'analyzing'), unit=_(b'revisions'), total=len(repo)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 rate = {}
df = False
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'date'):
df = dateutil.matchdate(opts[b'date'])
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Matt Mackall
scmutil: switch match users to supplying contexts...
r14671 m = scmutil.match(repo[None], pats, opts)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 def prep(ctx, fns):
Matt Mackall
walkchangerevs: yield contexts
r9654 rev = ctx.rev()
Augie Fackler
formatting: blacken the codebase...
r43346 if df and not df(ctx.date()[0]): # doesn't match date format
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 return
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: strip key earlier to avoid false negative seach in aliases
r14040 key = getkey(ctx).strip()
Augie Fackler
formatting: blacken the codebase...
r43346 key = amap.get(key, key) # alias remap
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if opts.get(b'changesets'):
Alexander Solovyov
churn: fix changeset count (broken by 9b127e888640)
r9670 rate[key] = (rate.get(key, (0,))[0] + 1, 0)
Alexander Solovyov
churn and stats commands merged
r7070 else:
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 parents = ctx.parents()
if len(parents) > 1:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.note(_(b'revision %d is a merge, ignoring...\n') % (rev,))
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 return
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 ctx1 = parents[0]
madhu@madhu
Returns lines changed for paths specified as arguments correctly....
r7870 lines = changedlines(ui, repo, ctx1, ctx, fns)
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 rate[key] = [r + l for r, l in zip(rate.get(key, (0, 0)), lines)]
Patrick Mezard
Make churn an official extension
r6348
Martin von Zweigbergk
churn: use progess helper...
r38420 progress.increment()
Patrick Mezard
Make churn an official extension
r6348
Matt Mackall
walkchangerevs: drop ui arg
r9665 for ctx in cmdutil.walkchangerevs(repo, m, opts, prep):
Matt Mackall
walkchangerevs: move 'add' to callback...
r9662 continue
Martin von Zweigbergk
churn: use progess helper...
r38420 progress.complete()
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 return rate
Augie Fackler
formatting: blacken the codebase...
r43346 @command(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'churn',
Augie Fackler
formatting: blacken the codebase...
r43346 [
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'r',
b'rev',
Augie Fackler
formatting: blacken the codebase...
r43346 [],
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'count rate for the specified revision or revset'),
_(b'REV'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'd',
b'date',
b'',
_(b'count rate for revisions matching date spec'),
_(b'DATE'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b't',
b'oldtemplate',
b'',
_(b'template to group changesets (DEPRECATED)'),
_(b'TEMPLATE'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'T',
b'template',
b'{author|email}',
_(b'template to group changesets'),
_(b'TEMPLATE'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'f',
b'dateformat',
b'',
_(b'strftime-compatible format for grouping by date'),
_(b'FORMAT'),
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 (b'c', b'changesets', False, _(b'count rate by number of changesets')),
(b's', b'sort', False, _(b'sort by key (default: sort by count)')),
(b'', b'diffstat', False, _(b'display added/removed lines separately')),
(b'', b'aliases', b'', _(b'file with email aliases'), _(b'FILE')),
Augie Fackler
formatting: blacken the codebase...
r43346 ]
+ cmdutil.walkopts,
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b"hg churn [-d DATE] [-r REV] [--aliases FILE] [FILE]"),
rdamazio@google.com
help: assigning categories to existing commands...
r40329 helpcategory=command.CATEGORY_MAINTENANCE,
Augie Fackler
formatting: blacken the codebase...
r43346 inferrepo=True,
)
Alexander Solovyov
churn and stats commands merged
r7070 def churn(ui, repo, *pats, **opts):
Cédric Duval
churn: improve description...
r8823 '''histogram of changes to the repository
Patrick Mezard
Make churn an official extension
r6348
Cédric Duval
churn: improve description...
r8823 This command will display a histogram representing the number
of changed lines or revisions, grouped according to the given
template. The default template will group changes by author.
The --dateformat option may be used to group the results by
date instead.
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Cédric Duval
churn: improve description...
r8823 Statistics are based on the number of changed lines, or
alternatively the number of matching revisions if the
--changesets option is specified.
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Martin Geisler
churn: use reST syntax for literal blocks
r9205 Examples::
Dirkjan Ochtman
convert comments to docstrings in a bunch of extensions
r6666
Alexander Solovyov
churn and stats commands merged
r7070 # display count of changed lines for every committer
Matt Harbison
churn: use the non-deprecated template option in the examples
r32229 hg churn -T "{author|email}"
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
# display daily activity graph
FUJIWARA Katsunori
doc: use double quotation mark to quote arguments in examples for Windows users...
r19959 hg churn -f "%H" -s -c
Dirkjan Ochtman
convert comments to docstrings in a bunch of extensions
r6666
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # display activity of developers by month
FUJIWARA Katsunori
doc: use double quotation mark to quote arguments in examples for Windows users...
r19959 hg churn -f "%Y-%m" -s -c
Patrick Mezard
Make churn an official extension
r6348
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 # display count of lines changed in every year
FUJIWARA Katsunori
doc: use double quotation mark to quote arguments in examples for Windows users...
r19959 hg churn -f "%Y" -s
Alexander Solovyov
churn and stats commands merged
r7070
Cédric Duval
churn: improve description...
r8823 It is possible to map alternate email addresses to a main address
Martin Geisler
churn: wrap docstrings at 70 characters
r9254 by providing a file using the following format::
Dirkjan Ochtman
kill trailing whitespace
r8843
Alexander Solovyov
churn: support spaces in aliases (issue2222)
r11264 <alias email> = <actual email>
Martin Geisler
churn: use .hgchurn in repo root as default map file
r8254
Martin Geisler
churn: wrap docstrings at 70 characters
r9254 Such a file may be specified with the --aliases option, otherwise
a .hgchurn file will be looked for in the working directory root.
Matthew Turk
churn: split email aliases from the right...
r19464 Aliases will be split from the rightmost "=".
Martin Geisler
churn: use .hgchurn in repo root as default map file
r8254 '''
Augie Fackler
formatting: blacken the codebase...
r43346
Patrick Mezard
Make churn an official extension
r6348 def pad(s, l):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return s + b" " * (l - encoding.colwidth(s))
Patrick Mezard
Make churn an official extension
r6348
amap = {}
Pulkit Goyal
py3: handle keyword arguments in hgext/churn.py...
r34975 aliases = opts.get(r'aliases')
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 if not aliases and os.path.exists(repo.wjoin(b'.hgchurn')):
aliases = repo.wjoin(b'.hgchurn')
Patrick Mezard
Make churn an official extension
r6348 if aliases:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 for l in open(aliases, b"rb"):
Martin Geisler
churn: do not crash on malformed lines in alias file
r12069 try:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 alias, actual = l.rsplit(b'=' in l and b'=' or None, 1)
Martin Geisler
churn: do not crash on malformed lines in alias file
r12069 amap[alias.strip()] = actual.strip()
except ValueError:
l = l.strip()
if l:
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(_(b"skipping malformed alias: %s\n") % l)
Ronny Pfannschmidt
churn: do not crash on empty lines in alias file
r12068 continue
Patrick Mezard
Make churn an official extension
r6348
Pulkit Goyal
py3: convert dict.items() to list explicitly...
r36410 rate = list(countrate(ui, repo, amap, *pats, **opts).items())
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065 if not rate:
Patrick Mezard
Make churn an official extension
r6348 return
Pulkit Goyal
py3: handle keyword arguments in hgext/churn.py...
r34975 if opts.get(r'sort'):
Mads Kiilerich
churn: sort users with same churn by name...
r18369 rate.sort()
else:
rate.sort(key=lambda x: (-sum(x[1]), x))
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Nicolas Dumazet
churn: issue833 was reintroduced in 9bc46d069a76, correct it and add a test
r9388 # Be careful not to have a zero maxcount (issue833)
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 maxcount = float(max(sum(v) for k, v in rate)) or 1.0
Nicolas Dumazet
churn: use genexps now that we dropped 2.3 compatibility
r9390 maxname = max(len(k) for k, v in rate)
Patrick Mezard
Make churn an official extension
r6348
Augie Fackler
termwidth: move to ui.ui from util
r12689 ttywidth = ui.termwidth()
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.debug(b"assuming %i character terminal\n" % ttywidth)
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 width = ttywidth - maxname - 2 - 2 - 2
Alexander Solovyov
churn: generalisation, now it is possible to see statistics grouped by custom template
r7065
Pulkit Goyal
py3: handle keyword arguments in hgext/churn.py...
r34975 if opts.get(r'diffstat'):
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 width -= 15
Augie Fackler
formatting: blacken the codebase...
r43346
Renato Cunha
churn: remove tuple parameter unpacking (deprecated in py3k)
r11501 def format(name, diffstat):
added, removed = diffstat
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"%s %15s %s%s\n" % (
Augie Fackler
formatting: blacken the codebase...
r43346 pad(name, maxname),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'+%d/-%d' % (added, removed),
ui.label(b'+' * charnum(added), b'diffstat.inserted'),
ui.label(b'-' * charnum(removed), b'diffstat.deleted'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 else:
width -= 6
Augie Fackler
formatting: blacken the codebase...
r43346
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669 def format(name, count):
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 return b"%s %6d %s\n" % (
Augie Fackler
formatting: blacken the codebase...
r43346 pad(name, maxname),
sum(count),
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'*' * charnum(sum(count)),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669
def charnum(count):
Augie Fackler
churn: remove redundant round()...
r40300 return int(count * width // maxcount)
Alexander Solovyov
churn: ability to display added/removed lines separately
r9669
for name, count in rate:
Steve Borho
Backed out changeset: e1dde7363601
r11310 ui.write(format(name, count))