Patchwork [6,of,6] debugcommands: move 'debugrevlog' in the new module

login
register
mail settings
Submitter Pierre-Yves David
Date Feb. 14, 2017, 6:36 p.m.
Message ID <9e0fc045b53a2a6d8759.1487097383@nodosa.octopoid.net>
Download mbox | patch
Permalink /patch/18486/
State Accepted
Headers show

Comments

Pierre-Yves David - Feb. 14, 2017, 6:36 p.m.
# HG changeset patch
# User Pierre-Yves David <pierre-yves.david@ens-lyon.org>
# Date 1486026160 -3600
#      Thu Feb 02 10:02:40 2017 +0100
# Node ID 9e0fc045b53a2a6d875913514903f5555386fff8
# Parent  63c9196e60144b261decc768ad13958dfd15fd4e
# EXP-Topic debugcommands
debugcommands: move 'debugrevlog' in the new module
Augie Fackler - Feb. 14, 2017, 6:39 p.m.
On Tue, Feb 14, 2017 at 07:36:23PM +0100, Pierre-Yves David wrote:
> # HG changeset patch
> # User Pierre-Yves David <pierre-yves.david@ens-lyon.org>
> # Date 1486026160 -3600
> #      Thu Feb 02 10:02:40 2017 +0100
> # Node ID 9e0fc045b53a2a6d875913514903f5555386fff8
> # Parent  63c9196e60144b261decc768ad13958dfd15fd4e
> # EXP-Topic debugcommands
> debugcommands: move 'debugrevlog' in the new module

Queued these, thanks.

>
> diff -r 63c9196e6014 -r 9e0fc045b53a mercurial/commands.py
> --- a/mercurial/commands.py	Thu Feb 02 10:01:54 2017 +0100
> +++ b/mercurial/commands.py	Thu Feb 02 10:02:40 2017 +0100
> @@ -11,7 +11,6 @@ import difflib
>  import errno
>  import os
>  import re
> -import string
>  import time
>
>  from .i18n import _
> @@ -47,7 +46,6 @@ from . import (
>      patch,
>      phases,
>      pycompat,
> -    revlog,
>      revset,
>      scmutil,
>      server,
> @@ -1858,226 +1856,6 @@ def copy(ui, repo, *pats, **opts):
>      with repo.wlock(False):
>          return cmdutil.copy(ui, repo, pats, opts)
>
> -@command('debugrevlog', debugrevlogopts +
> -    [('d', 'dump', False, _('dump index data'))],
> -    _('-c|-m|FILE'),
> -    optionalrepo=True)
> -def debugrevlog(ui, repo, file_=None, **opts):
> -    """show data and statistics about a revlog"""
> -    r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
> -
> -    if opts.get("dump"):
> -        numrevs = len(r)
> -        ui.write(("# rev p1rev p2rev start   end deltastart base   p1   p2"
> -                 " rawsize totalsize compression heads chainlen\n"))
> -        ts = 0
> -        heads = set()
> -
> -        for rev in xrange(numrevs):
> -            dbase = r.deltaparent(rev)
> -            if dbase == -1:
> -                dbase = rev
> -            cbase = r.chainbase(rev)
> -            clen = r.chainlen(rev)
> -            p1, p2 = r.parentrevs(rev)
> -            rs = r.rawsize(rev)
> -            ts = ts + rs
> -            heads -= set(r.parentrevs(rev))
> -            heads.add(rev)
> -            try:
> -                compression = ts / r.end(rev)
> -            except ZeroDivisionError:
> -                compression = 0
> -            ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
> -                     "%11d %5d %8d\n" %
> -                     (rev, p1, p2, r.start(rev), r.end(rev),
> -                      r.start(dbase), r.start(cbase),
> -                      r.start(p1), r.start(p2),
> -                      rs, ts, compression, len(heads), clen))
> -        return 0
> -
> -    v = r.version
> -    format = v & 0xFFFF
> -    flags = []
> -    gdelta = False
> -    if v & revlog.REVLOGNGINLINEDATA:
> -        flags.append('inline')
> -    if v & revlog.REVLOGGENERALDELTA:
> -        gdelta = True
> -        flags.append('generaldelta')
> -    if not flags:
> -        flags = ['(none)']
> -
> -    nummerges = 0
> -    numfull = 0
> -    numprev = 0
> -    nump1 = 0
> -    nump2 = 0
> -    numother = 0
> -    nump1prev = 0
> -    nump2prev = 0
> -    chainlengths = []
> -
> -    datasize = [None, 0, 0]
> -    fullsize = [None, 0, 0]
> -    deltasize = [None, 0, 0]
> -    chunktypecounts = {}
> -    chunktypesizes = {}
> -
> -    def addsize(size, l):
> -        if l[0] is None or size < l[0]:
> -            l[0] = size
> -        if size > l[1]:
> -            l[1] = size
> -        l[2] += size
> -
> -    numrevs = len(r)
> -    for rev in xrange(numrevs):
> -        p1, p2 = r.parentrevs(rev)
> -        delta = r.deltaparent(rev)
> -        if format > 0:
> -            addsize(r.rawsize(rev), datasize)
> -        if p2 != nullrev:
> -            nummerges += 1
> -        size = r.length(rev)
> -        if delta == nullrev:
> -            chainlengths.append(0)
> -            numfull += 1
> -            addsize(size, fullsize)
> -        else:
> -            chainlengths.append(chainlengths[delta] + 1)
> -            addsize(size, deltasize)
> -            if delta == rev - 1:
> -                numprev += 1
> -                if delta == p1:
> -                    nump1prev += 1
> -                elif delta == p2:
> -                    nump2prev += 1
> -            elif delta == p1:
> -                nump1 += 1
> -            elif delta == p2:
> -                nump2 += 1
> -            elif delta != nullrev:
> -                numother += 1
> -
> -        # Obtain data on the raw chunks in the revlog.
> -        chunk = r._chunkraw(rev, rev)[1]
> -        if chunk:
> -            chunktype = chunk[0]
> -        else:
> -            chunktype = 'empty'
> -
> -        if chunktype not in chunktypecounts:
> -            chunktypecounts[chunktype] = 0
> -            chunktypesizes[chunktype] = 0
> -
> -        chunktypecounts[chunktype] += 1
> -        chunktypesizes[chunktype] += size
> -
> -    # Adjust size min value for empty cases
> -    for size in (datasize, fullsize, deltasize):
> -        if size[0] is None:
> -            size[0] = 0
> -
> -    numdeltas = numrevs - numfull
> -    numoprev = numprev - nump1prev - nump2prev
> -    totalrawsize = datasize[2]
> -    datasize[2] /= numrevs
> -    fulltotal = fullsize[2]
> -    fullsize[2] /= numfull
> -    deltatotal = deltasize[2]
> -    if numrevs - numfull > 0:
> -        deltasize[2] /= numrevs - numfull
> -    totalsize = fulltotal + deltatotal
> -    avgchainlen = sum(chainlengths) / numrevs
> -    maxchainlen = max(chainlengths)
> -    compratio = 1
> -    if totalsize:
> -        compratio = totalrawsize / totalsize
> -
> -    basedfmtstr = '%%%dd\n'
> -    basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
> -
> -    def dfmtstr(max):
> -        return basedfmtstr % len(str(max))
> -    def pcfmtstr(max, padding=0):
> -        return basepcfmtstr % (len(str(max)), ' ' * padding)
> -
> -    def pcfmt(value, total):
> -        if total:
> -            return (value, 100 * float(value) / total)
> -        else:
> -            return value, 100.0
> -
> -    ui.write(('format : %d\n') % format)
> -    ui.write(('flags  : %s\n') % ', '.join(flags))
> -
> -    ui.write('\n')
> -    fmt = pcfmtstr(totalsize)
> -    fmt2 = dfmtstr(totalsize)
> -    ui.write(('revisions     : ') + fmt2 % numrevs)
> -    ui.write(('    merges    : ') + fmt % pcfmt(nummerges, numrevs))
> -    ui.write(('    normal    : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
> -    ui.write(('revisions     : ') + fmt2 % numrevs)
> -    ui.write(('    full      : ') + fmt % pcfmt(numfull, numrevs))
> -    ui.write(('    deltas    : ') + fmt % pcfmt(numdeltas, numrevs))
> -    ui.write(('revision size : ') + fmt2 % totalsize)
> -    ui.write(('    full      : ') + fmt % pcfmt(fulltotal, totalsize))
> -    ui.write(('    deltas    : ') + fmt % pcfmt(deltatotal, totalsize))
> -
> -    def fmtchunktype(chunktype):
> -        if chunktype == 'empty':
> -            return '    %s     : ' % chunktype
> -        elif chunktype in string.ascii_letters:
> -            return '    0x%s (%s)  : ' % (hex(chunktype), chunktype)
> -        else:
> -            return '    0x%s      : ' % hex(chunktype)
> -
> -    ui.write('\n')
> -    ui.write(('chunks        : ') + fmt2 % numrevs)
> -    for chunktype in sorted(chunktypecounts):
> -        ui.write(fmtchunktype(chunktype))
> -        ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
> -    ui.write(('chunks size   : ') + fmt2 % totalsize)
> -    for chunktype in sorted(chunktypecounts):
> -        ui.write(fmtchunktype(chunktype))
> -        ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
> -
> -    ui.write('\n')
> -    fmt = dfmtstr(max(avgchainlen, compratio))
> -    ui.write(('avg chain length  : ') + fmt % avgchainlen)
> -    ui.write(('max chain length  : ') + fmt % maxchainlen)
> -    ui.write(('compression ratio : ') + fmt % compratio)
> -
> -    if format > 0:
> -        ui.write('\n')
> -        ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
> -                 % tuple(datasize))
> -    ui.write(('full revision size (min/max/avg)     : %d / %d / %d\n')
> -             % tuple(fullsize))
> -    ui.write(('delta size (min/max/avg)             : %d / %d / %d\n')
> -             % tuple(deltasize))
> -
> -    if numdeltas > 0:
> -        ui.write('\n')
> -        fmt = pcfmtstr(numdeltas)
> -        fmt2 = pcfmtstr(numdeltas, 4)
> -        ui.write(('deltas against prev  : ') + fmt % pcfmt(numprev, numdeltas))
> -        if numprev > 0:
> -            ui.write(('    where prev = p1  : ') + fmt2 % pcfmt(nump1prev,
> -                                                              numprev))
> -            ui.write(('    where prev = p2  : ') + fmt2 % pcfmt(nump2prev,
> -                                                              numprev))
> -            ui.write(('    other            : ') + fmt2 % pcfmt(numoprev,
> -                                                              numprev))
> -        if gdelta:
> -            ui.write(('deltas against p1    : ')
> -                     + fmt % pcfmt(nump1, numdeltas))
> -            ui.write(('deltas against p2    : ')
> -                     + fmt % pcfmt(nump2, numdeltas))
> -            ui.write(('deltas against other : ') + fmt % pcfmt(numother,
> -                                                             numdeltas))
> -
>  @command('debugrevspec',
>      [('', 'optimize', None,
>        _('print parsed tree after optimizing (DEPRECATED)')),
> diff -r 63c9196e6014 -r 9e0fc045b53a mercurial/debugcommands.py
> --- a/mercurial/debugcommands.py	Thu Feb 02 10:01:54 2017 +0100
> +++ b/mercurial/debugcommands.py	Thu Feb 02 10:02:40 2017 +0100
> @@ -12,6 +12,7 @@ import operator
>  import os
>  import random
>  import socket
> +import string
>  import sys
>  import tempfile
>  import time
> @@ -22,6 +23,7 @@ from .node import (
>      hex,
>      nullhex,
>      nullid,
> +    nullrev,
>      short,
>  )
>  from . import (
> @@ -1517,6 +1519,226 @@ def debugrename(ui, repo, file1, *pats,
>          else:
>              ui.write(_("%s not renamed\n") % rel)
>
> +@command('debugrevlog', commands.debugrevlogopts +
> +    [('d', 'dump', False, _('dump index data'))],
> +    _('-c|-m|FILE'),
> +    optionalrepo=True)
> +def debugrevlog(ui, repo, file_=None, **opts):
> +    """show data and statistics about a revlog"""
> +    r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
> +
> +    if opts.get("dump"):
> +        numrevs = len(r)
> +        ui.write(("# rev p1rev p2rev start   end deltastart base   p1   p2"
> +                 " rawsize totalsize compression heads chainlen\n"))
> +        ts = 0
> +        heads = set()
> +
> +        for rev in xrange(numrevs):
> +            dbase = r.deltaparent(rev)
> +            if dbase == -1:
> +                dbase = rev
> +            cbase = r.chainbase(rev)
> +            clen = r.chainlen(rev)
> +            p1, p2 = r.parentrevs(rev)
> +            rs = r.rawsize(rev)
> +            ts = ts + rs
> +            heads -= set(r.parentrevs(rev))
> +            heads.add(rev)
> +            try:
> +                compression = ts / r.end(rev)
> +            except ZeroDivisionError:
> +                compression = 0
> +            ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
> +                     "%11d %5d %8d\n" %
> +                     (rev, p1, p2, r.start(rev), r.end(rev),
> +                      r.start(dbase), r.start(cbase),
> +                      r.start(p1), r.start(p2),
> +                      rs, ts, compression, len(heads), clen))
> +        return 0
> +
> +    v = r.version
> +    format = v & 0xFFFF
> +    flags = []
> +    gdelta = False
> +    if v & revlog.REVLOGNGINLINEDATA:
> +        flags.append('inline')
> +    if v & revlog.REVLOGGENERALDELTA:
> +        gdelta = True
> +        flags.append('generaldelta')
> +    if not flags:
> +        flags = ['(none)']
> +
> +    nummerges = 0
> +    numfull = 0
> +    numprev = 0
> +    nump1 = 0
> +    nump2 = 0
> +    numother = 0
> +    nump1prev = 0
> +    nump2prev = 0
> +    chainlengths = []
> +
> +    datasize = [None, 0, 0]
> +    fullsize = [None, 0, 0]
> +    deltasize = [None, 0, 0]
> +    chunktypecounts = {}
> +    chunktypesizes = {}
> +
> +    def addsize(size, l):
> +        if l[0] is None or size < l[0]:
> +            l[0] = size
> +        if size > l[1]:
> +            l[1] = size
> +        l[2] += size
> +
> +    numrevs = len(r)
> +    for rev in xrange(numrevs):
> +        p1, p2 = r.parentrevs(rev)
> +        delta = r.deltaparent(rev)
> +        if format > 0:
> +            addsize(r.rawsize(rev), datasize)
> +        if p2 != nullrev:
> +            nummerges += 1
> +        size = r.length(rev)
> +        if delta == nullrev:
> +            chainlengths.append(0)
> +            numfull += 1
> +            addsize(size, fullsize)
> +        else:
> +            chainlengths.append(chainlengths[delta] + 1)
> +            addsize(size, deltasize)
> +            if delta == rev - 1:
> +                numprev += 1
> +                if delta == p1:
> +                    nump1prev += 1
> +                elif delta == p2:
> +                    nump2prev += 1
> +            elif delta == p1:
> +                nump1 += 1
> +            elif delta == p2:
> +                nump2 += 1
> +            elif delta != nullrev:
> +                numother += 1
> +
> +        # Obtain data on the raw chunks in the revlog.
> +        chunk = r._chunkraw(rev, rev)[1]
> +        if chunk:
> +            chunktype = chunk[0]
> +        else:
> +            chunktype = 'empty'
> +
> +        if chunktype not in chunktypecounts:
> +            chunktypecounts[chunktype] = 0
> +            chunktypesizes[chunktype] = 0
> +
> +        chunktypecounts[chunktype] += 1
> +        chunktypesizes[chunktype] += size
> +
> +    # Adjust size min value for empty cases
> +    for size in (datasize, fullsize, deltasize):
> +        if size[0] is None:
> +            size[0] = 0
> +
> +    numdeltas = numrevs - numfull
> +    numoprev = numprev - nump1prev - nump2prev
> +    totalrawsize = datasize[2]
> +    datasize[2] /= numrevs
> +    fulltotal = fullsize[2]
> +    fullsize[2] /= numfull
> +    deltatotal = deltasize[2]
> +    if numrevs - numfull > 0:
> +        deltasize[2] /= numrevs - numfull
> +    totalsize = fulltotal + deltatotal
> +    avgchainlen = sum(chainlengths) / numrevs
> +    maxchainlen = max(chainlengths)
> +    compratio = 1
> +    if totalsize:
> +        compratio = totalrawsize / totalsize
> +
> +    basedfmtstr = '%%%dd\n'
> +    basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
> +
> +    def dfmtstr(max):
> +        return basedfmtstr % len(str(max))
> +    def pcfmtstr(max, padding=0):
> +        return basepcfmtstr % (len(str(max)), ' ' * padding)
> +
> +    def pcfmt(value, total):
> +        if total:
> +            return (value, 100 * float(value) / total)
> +        else:
> +            return value, 100.0
> +
> +    ui.write(('format : %d\n') % format)
> +    ui.write(('flags  : %s\n') % ', '.join(flags))
> +
> +    ui.write('\n')
> +    fmt = pcfmtstr(totalsize)
> +    fmt2 = dfmtstr(totalsize)
> +    ui.write(('revisions     : ') + fmt2 % numrevs)
> +    ui.write(('    merges    : ') + fmt % pcfmt(nummerges, numrevs))
> +    ui.write(('    normal    : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
> +    ui.write(('revisions     : ') + fmt2 % numrevs)
> +    ui.write(('    full      : ') + fmt % pcfmt(numfull, numrevs))
> +    ui.write(('    deltas    : ') + fmt % pcfmt(numdeltas, numrevs))
> +    ui.write(('revision size : ') + fmt2 % totalsize)
> +    ui.write(('    full      : ') + fmt % pcfmt(fulltotal, totalsize))
> +    ui.write(('    deltas    : ') + fmt % pcfmt(deltatotal, totalsize))
> +
> +    def fmtchunktype(chunktype):
> +        if chunktype == 'empty':
> +            return '    %s     : ' % chunktype
> +        elif chunktype in string.ascii_letters:
> +            return '    0x%s (%s)  : ' % (hex(chunktype), chunktype)
> +        else:
> +            return '    0x%s      : ' % hex(chunktype)
> +
> +    ui.write('\n')
> +    ui.write(('chunks        : ') + fmt2 % numrevs)
> +    for chunktype in sorted(chunktypecounts):
> +        ui.write(fmtchunktype(chunktype))
> +        ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
> +    ui.write(('chunks size   : ') + fmt2 % totalsize)
> +    for chunktype in sorted(chunktypecounts):
> +        ui.write(fmtchunktype(chunktype))
> +        ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
> +
> +    ui.write('\n')
> +    fmt = dfmtstr(max(avgchainlen, compratio))
> +    ui.write(('avg chain length  : ') + fmt % avgchainlen)
> +    ui.write(('max chain length  : ') + fmt % maxchainlen)
> +    ui.write(('compression ratio : ') + fmt % compratio)
> +
> +    if format > 0:
> +        ui.write('\n')
> +        ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
> +                 % tuple(datasize))
> +    ui.write(('full revision size (min/max/avg)     : %d / %d / %d\n')
> +             % tuple(fullsize))
> +    ui.write(('delta size (min/max/avg)             : %d / %d / %d\n')
> +             % tuple(deltasize))
> +
> +    if numdeltas > 0:
> +        ui.write('\n')
> +        fmt = pcfmtstr(numdeltas)
> +        fmt2 = pcfmtstr(numdeltas, 4)
> +        ui.write(('deltas against prev  : ') + fmt % pcfmt(numprev, numdeltas))
> +        if numprev > 0:
> +            ui.write(('    where prev = p1  : ') + fmt2 % pcfmt(nump1prev,
> +                                                              numprev))
> +            ui.write(('    where prev = p2  : ') + fmt2 % pcfmt(nump2prev,
> +                                                              numprev))
> +            ui.write(('    other            : ') + fmt2 % pcfmt(numoprev,
> +                                                              numprev))
> +        if gdelta:
> +            ui.write(('deltas against p1    : ')
> +                     + fmt % pcfmt(nump1, numdeltas))
> +            ui.write(('deltas against p2    : ')
> +                     + fmt % pcfmt(nump2, numdeltas))
> +            ui.write(('deltas against other : ') + fmt % pcfmt(numother,
> +                                                             numdeltas))
> +
>  @command('debugupgraderepo', [
>      ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
>      ('', 'run', False, _('performs an upgrade')),
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel

Patch

diff -r 63c9196e6014 -r 9e0fc045b53a mercurial/commands.py
--- a/mercurial/commands.py	Thu Feb 02 10:01:54 2017 +0100
+++ b/mercurial/commands.py	Thu Feb 02 10:02:40 2017 +0100
@@ -11,7 +11,6 @@  import difflib
 import errno
 import os
 import re
-import string
 import time
 
 from .i18n import _
@@ -47,7 +46,6 @@  from . import (
     patch,
     phases,
     pycompat,
-    revlog,
     revset,
     scmutil,
     server,
@@ -1858,226 +1856,6 @@  def copy(ui, repo, *pats, **opts):
     with repo.wlock(False):
         return cmdutil.copy(ui, repo, pats, opts)
 
-@command('debugrevlog', debugrevlogopts +
-    [('d', 'dump', False, _('dump index data'))],
-    _('-c|-m|FILE'),
-    optionalrepo=True)
-def debugrevlog(ui, repo, file_=None, **opts):
-    """show data and statistics about a revlog"""
-    r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
-
-    if opts.get("dump"):
-        numrevs = len(r)
-        ui.write(("# rev p1rev p2rev start   end deltastart base   p1   p2"
-                 " rawsize totalsize compression heads chainlen\n"))
-        ts = 0
-        heads = set()
-
-        for rev in xrange(numrevs):
-            dbase = r.deltaparent(rev)
-            if dbase == -1:
-                dbase = rev
-            cbase = r.chainbase(rev)
-            clen = r.chainlen(rev)
-            p1, p2 = r.parentrevs(rev)
-            rs = r.rawsize(rev)
-            ts = ts + rs
-            heads -= set(r.parentrevs(rev))
-            heads.add(rev)
-            try:
-                compression = ts / r.end(rev)
-            except ZeroDivisionError:
-                compression = 0
-            ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
-                     "%11d %5d %8d\n" %
-                     (rev, p1, p2, r.start(rev), r.end(rev),
-                      r.start(dbase), r.start(cbase),
-                      r.start(p1), r.start(p2),
-                      rs, ts, compression, len(heads), clen))
-        return 0
-
-    v = r.version
-    format = v & 0xFFFF
-    flags = []
-    gdelta = False
-    if v & revlog.REVLOGNGINLINEDATA:
-        flags.append('inline')
-    if v & revlog.REVLOGGENERALDELTA:
-        gdelta = True
-        flags.append('generaldelta')
-    if not flags:
-        flags = ['(none)']
-
-    nummerges = 0
-    numfull = 0
-    numprev = 0
-    nump1 = 0
-    nump2 = 0
-    numother = 0
-    nump1prev = 0
-    nump2prev = 0
-    chainlengths = []
-
-    datasize = [None, 0, 0]
-    fullsize = [None, 0, 0]
-    deltasize = [None, 0, 0]
-    chunktypecounts = {}
-    chunktypesizes = {}
-
-    def addsize(size, l):
-        if l[0] is None or size < l[0]:
-            l[0] = size
-        if size > l[1]:
-            l[1] = size
-        l[2] += size
-
-    numrevs = len(r)
-    for rev in xrange(numrevs):
-        p1, p2 = r.parentrevs(rev)
-        delta = r.deltaparent(rev)
-        if format > 0:
-            addsize(r.rawsize(rev), datasize)
-        if p2 != nullrev:
-            nummerges += 1
-        size = r.length(rev)
-        if delta == nullrev:
-            chainlengths.append(0)
-            numfull += 1
-            addsize(size, fullsize)
-        else:
-            chainlengths.append(chainlengths[delta] + 1)
-            addsize(size, deltasize)
-            if delta == rev - 1:
-                numprev += 1
-                if delta == p1:
-                    nump1prev += 1
-                elif delta == p2:
-                    nump2prev += 1
-            elif delta == p1:
-                nump1 += 1
-            elif delta == p2:
-                nump2 += 1
-            elif delta != nullrev:
-                numother += 1
-
-        # Obtain data on the raw chunks in the revlog.
-        chunk = r._chunkraw(rev, rev)[1]
-        if chunk:
-            chunktype = chunk[0]
-        else:
-            chunktype = 'empty'
-
-        if chunktype not in chunktypecounts:
-            chunktypecounts[chunktype] = 0
-            chunktypesizes[chunktype] = 0
-
-        chunktypecounts[chunktype] += 1
-        chunktypesizes[chunktype] += size
-
-    # Adjust size min value for empty cases
-    for size in (datasize, fullsize, deltasize):
-        if size[0] is None:
-            size[0] = 0
-
-    numdeltas = numrevs - numfull
-    numoprev = numprev - nump1prev - nump2prev
-    totalrawsize = datasize[2]
-    datasize[2] /= numrevs
-    fulltotal = fullsize[2]
-    fullsize[2] /= numfull
-    deltatotal = deltasize[2]
-    if numrevs - numfull > 0:
-        deltasize[2] /= numrevs - numfull
-    totalsize = fulltotal + deltatotal
-    avgchainlen = sum(chainlengths) / numrevs
-    maxchainlen = max(chainlengths)
-    compratio = 1
-    if totalsize:
-        compratio = totalrawsize / totalsize
-
-    basedfmtstr = '%%%dd\n'
-    basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
-
-    def dfmtstr(max):
-        return basedfmtstr % len(str(max))
-    def pcfmtstr(max, padding=0):
-        return basepcfmtstr % (len(str(max)), ' ' * padding)
-
-    def pcfmt(value, total):
-        if total:
-            return (value, 100 * float(value) / total)
-        else:
-            return value, 100.0
-
-    ui.write(('format : %d\n') % format)
-    ui.write(('flags  : %s\n') % ', '.join(flags))
-
-    ui.write('\n')
-    fmt = pcfmtstr(totalsize)
-    fmt2 = dfmtstr(totalsize)
-    ui.write(('revisions     : ') + fmt2 % numrevs)
-    ui.write(('    merges    : ') + fmt % pcfmt(nummerges, numrevs))
-    ui.write(('    normal    : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
-    ui.write(('revisions     : ') + fmt2 % numrevs)
-    ui.write(('    full      : ') + fmt % pcfmt(numfull, numrevs))
-    ui.write(('    deltas    : ') + fmt % pcfmt(numdeltas, numrevs))
-    ui.write(('revision size : ') + fmt2 % totalsize)
-    ui.write(('    full      : ') + fmt % pcfmt(fulltotal, totalsize))
-    ui.write(('    deltas    : ') + fmt % pcfmt(deltatotal, totalsize))
-
-    def fmtchunktype(chunktype):
-        if chunktype == 'empty':
-            return '    %s     : ' % chunktype
-        elif chunktype in string.ascii_letters:
-            return '    0x%s (%s)  : ' % (hex(chunktype), chunktype)
-        else:
-            return '    0x%s      : ' % hex(chunktype)
-
-    ui.write('\n')
-    ui.write(('chunks        : ') + fmt2 % numrevs)
-    for chunktype in sorted(chunktypecounts):
-        ui.write(fmtchunktype(chunktype))
-        ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
-    ui.write(('chunks size   : ') + fmt2 % totalsize)
-    for chunktype in sorted(chunktypecounts):
-        ui.write(fmtchunktype(chunktype))
-        ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
-
-    ui.write('\n')
-    fmt = dfmtstr(max(avgchainlen, compratio))
-    ui.write(('avg chain length  : ') + fmt % avgchainlen)
-    ui.write(('max chain length  : ') + fmt % maxchainlen)
-    ui.write(('compression ratio : ') + fmt % compratio)
-
-    if format > 0:
-        ui.write('\n')
-        ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
-                 % tuple(datasize))
-    ui.write(('full revision size (min/max/avg)     : %d / %d / %d\n')
-             % tuple(fullsize))
-    ui.write(('delta size (min/max/avg)             : %d / %d / %d\n')
-             % tuple(deltasize))
-
-    if numdeltas > 0:
-        ui.write('\n')
-        fmt = pcfmtstr(numdeltas)
-        fmt2 = pcfmtstr(numdeltas, 4)
-        ui.write(('deltas against prev  : ') + fmt % pcfmt(numprev, numdeltas))
-        if numprev > 0:
-            ui.write(('    where prev = p1  : ') + fmt2 % pcfmt(nump1prev,
-                                                              numprev))
-            ui.write(('    where prev = p2  : ') + fmt2 % pcfmt(nump2prev,
-                                                              numprev))
-            ui.write(('    other            : ') + fmt2 % pcfmt(numoprev,
-                                                              numprev))
-        if gdelta:
-            ui.write(('deltas against p1    : ')
-                     + fmt % pcfmt(nump1, numdeltas))
-            ui.write(('deltas against p2    : ')
-                     + fmt % pcfmt(nump2, numdeltas))
-            ui.write(('deltas against other : ') + fmt % pcfmt(numother,
-                                                             numdeltas))
-
 @command('debugrevspec',
     [('', 'optimize', None,
       _('print parsed tree after optimizing (DEPRECATED)')),
diff -r 63c9196e6014 -r 9e0fc045b53a mercurial/debugcommands.py
--- a/mercurial/debugcommands.py	Thu Feb 02 10:01:54 2017 +0100
+++ b/mercurial/debugcommands.py	Thu Feb 02 10:02:40 2017 +0100
@@ -12,6 +12,7 @@  import operator
 import os
 import random
 import socket
+import string
 import sys
 import tempfile
 import time
@@ -22,6 +23,7 @@  from .node import (
     hex,
     nullhex,
     nullid,
+    nullrev,
     short,
 )
 from . import (
@@ -1517,6 +1519,226 @@  def debugrename(ui, repo, file1, *pats, 
         else:
             ui.write(_("%s not renamed\n") % rel)
 
+@command('debugrevlog', commands.debugrevlogopts +
+    [('d', 'dump', False, _('dump index data'))],
+    _('-c|-m|FILE'),
+    optionalrepo=True)
+def debugrevlog(ui, repo, file_=None, **opts):
+    """show data and statistics about a revlog"""
+    r = cmdutil.openrevlog(repo, 'debugrevlog', file_, opts)
+
+    if opts.get("dump"):
+        numrevs = len(r)
+        ui.write(("# rev p1rev p2rev start   end deltastart base   p1   p2"
+                 " rawsize totalsize compression heads chainlen\n"))
+        ts = 0
+        heads = set()
+
+        for rev in xrange(numrevs):
+            dbase = r.deltaparent(rev)
+            if dbase == -1:
+                dbase = rev
+            cbase = r.chainbase(rev)
+            clen = r.chainlen(rev)
+            p1, p2 = r.parentrevs(rev)
+            rs = r.rawsize(rev)
+            ts = ts + rs
+            heads -= set(r.parentrevs(rev))
+            heads.add(rev)
+            try:
+                compression = ts / r.end(rev)
+            except ZeroDivisionError:
+                compression = 0
+            ui.write("%5d %5d %5d %5d %5d %10d %4d %4d %4d %7d %9d "
+                     "%11d %5d %8d\n" %
+                     (rev, p1, p2, r.start(rev), r.end(rev),
+                      r.start(dbase), r.start(cbase),
+                      r.start(p1), r.start(p2),
+                      rs, ts, compression, len(heads), clen))
+        return 0
+
+    v = r.version
+    format = v & 0xFFFF
+    flags = []
+    gdelta = False
+    if v & revlog.REVLOGNGINLINEDATA:
+        flags.append('inline')
+    if v & revlog.REVLOGGENERALDELTA:
+        gdelta = True
+        flags.append('generaldelta')
+    if not flags:
+        flags = ['(none)']
+
+    nummerges = 0
+    numfull = 0
+    numprev = 0
+    nump1 = 0
+    nump2 = 0
+    numother = 0
+    nump1prev = 0
+    nump2prev = 0
+    chainlengths = []
+
+    datasize = [None, 0, 0]
+    fullsize = [None, 0, 0]
+    deltasize = [None, 0, 0]
+    chunktypecounts = {}
+    chunktypesizes = {}
+
+    def addsize(size, l):
+        if l[0] is None or size < l[0]:
+            l[0] = size
+        if size > l[1]:
+            l[1] = size
+        l[2] += size
+
+    numrevs = len(r)
+    for rev in xrange(numrevs):
+        p1, p2 = r.parentrevs(rev)
+        delta = r.deltaparent(rev)
+        if format > 0:
+            addsize(r.rawsize(rev), datasize)
+        if p2 != nullrev:
+            nummerges += 1
+        size = r.length(rev)
+        if delta == nullrev:
+            chainlengths.append(0)
+            numfull += 1
+            addsize(size, fullsize)
+        else:
+            chainlengths.append(chainlengths[delta] + 1)
+            addsize(size, deltasize)
+            if delta == rev - 1:
+                numprev += 1
+                if delta == p1:
+                    nump1prev += 1
+                elif delta == p2:
+                    nump2prev += 1
+            elif delta == p1:
+                nump1 += 1
+            elif delta == p2:
+                nump2 += 1
+            elif delta != nullrev:
+                numother += 1
+
+        # Obtain data on the raw chunks in the revlog.
+        chunk = r._chunkraw(rev, rev)[1]
+        if chunk:
+            chunktype = chunk[0]
+        else:
+            chunktype = 'empty'
+
+        if chunktype not in chunktypecounts:
+            chunktypecounts[chunktype] = 0
+            chunktypesizes[chunktype] = 0
+
+        chunktypecounts[chunktype] += 1
+        chunktypesizes[chunktype] += size
+
+    # Adjust size min value for empty cases
+    for size in (datasize, fullsize, deltasize):
+        if size[0] is None:
+            size[0] = 0
+
+    numdeltas = numrevs - numfull
+    numoprev = numprev - nump1prev - nump2prev
+    totalrawsize = datasize[2]
+    datasize[2] /= numrevs
+    fulltotal = fullsize[2]
+    fullsize[2] /= numfull
+    deltatotal = deltasize[2]
+    if numrevs - numfull > 0:
+        deltasize[2] /= numrevs - numfull
+    totalsize = fulltotal + deltatotal
+    avgchainlen = sum(chainlengths) / numrevs
+    maxchainlen = max(chainlengths)
+    compratio = 1
+    if totalsize:
+        compratio = totalrawsize / totalsize
+
+    basedfmtstr = '%%%dd\n'
+    basepcfmtstr = '%%%dd %s(%%5.2f%%%%)\n'
+
+    def dfmtstr(max):
+        return basedfmtstr % len(str(max))
+    def pcfmtstr(max, padding=0):
+        return basepcfmtstr % (len(str(max)), ' ' * padding)
+
+    def pcfmt(value, total):
+        if total:
+            return (value, 100 * float(value) / total)
+        else:
+            return value, 100.0
+
+    ui.write(('format : %d\n') % format)
+    ui.write(('flags  : %s\n') % ', '.join(flags))
+
+    ui.write('\n')
+    fmt = pcfmtstr(totalsize)
+    fmt2 = dfmtstr(totalsize)
+    ui.write(('revisions     : ') + fmt2 % numrevs)
+    ui.write(('    merges    : ') + fmt % pcfmt(nummerges, numrevs))
+    ui.write(('    normal    : ') + fmt % pcfmt(numrevs - nummerges, numrevs))
+    ui.write(('revisions     : ') + fmt2 % numrevs)
+    ui.write(('    full      : ') + fmt % pcfmt(numfull, numrevs))
+    ui.write(('    deltas    : ') + fmt % pcfmt(numdeltas, numrevs))
+    ui.write(('revision size : ') + fmt2 % totalsize)
+    ui.write(('    full      : ') + fmt % pcfmt(fulltotal, totalsize))
+    ui.write(('    deltas    : ') + fmt % pcfmt(deltatotal, totalsize))
+
+    def fmtchunktype(chunktype):
+        if chunktype == 'empty':
+            return '    %s     : ' % chunktype
+        elif chunktype in string.ascii_letters:
+            return '    0x%s (%s)  : ' % (hex(chunktype), chunktype)
+        else:
+            return '    0x%s      : ' % hex(chunktype)
+
+    ui.write('\n')
+    ui.write(('chunks        : ') + fmt2 % numrevs)
+    for chunktype in sorted(chunktypecounts):
+        ui.write(fmtchunktype(chunktype))
+        ui.write(fmt % pcfmt(chunktypecounts[chunktype], numrevs))
+    ui.write(('chunks size   : ') + fmt2 % totalsize)
+    for chunktype in sorted(chunktypecounts):
+        ui.write(fmtchunktype(chunktype))
+        ui.write(fmt % pcfmt(chunktypesizes[chunktype], totalsize))
+
+    ui.write('\n')
+    fmt = dfmtstr(max(avgchainlen, compratio))
+    ui.write(('avg chain length  : ') + fmt % avgchainlen)
+    ui.write(('max chain length  : ') + fmt % maxchainlen)
+    ui.write(('compression ratio : ') + fmt % compratio)
+
+    if format > 0:
+        ui.write('\n')
+        ui.write(('uncompressed data size (min/max/avg) : %d / %d / %d\n')
+                 % tuple(datasize))
+    ui.write(('full revision size (min/max/avg)     : %d / %d / %d\n')
+             % tuple(fullsize))
+    ui.write(('delta size (min/max/avg)             : %d / %d / %d\n')
+             % tuple(deltasize))
+
+    if numdeltas > 0:
+        ui.write('\n')
+        fmt = pcfmtstr(numdeltas)
+        fmt2 = pcfmtstr(numdeltas, 4)
+        ui.write(('deltas against prev  : ') + fmt % pcfmt(numprev, numdeltas))
+        if numprev > 0:
+            ui.write(('    where prev = p1  : ') + fmt2 % pcfmt(nump1prev,
+                                                              numprev))
+            ui.write(('    where prev = p2  : ') + fmt2 % pcfmt(nump2prev,
+                                                              numprev))
+            ui.write(('    other            : ') + fmt2 % pcfmt(numoprev,
+                                                              numprev))
+        if gdelta:
+            ui.write(('deltas against p1    : ')
+                     + fmt % pcfmt(nump1, numdeltas))
+            ui.write(('deltas against p2    : ')
+                     + fmt % pcfmt(nump2, numdeltas))
+            ui.write(('deltas against other : ') + fmt % pcfmt(numother,
+                                                             numdeltas))
+
 @command('debugupgraderepo', [
     ('o', 'optimize', [], _('extra optimization to perform'), _('NAME')),
     ('', 'run', False, _('performs an upgrade')),