contrib/shrink-revlog.py
author Patrick Mezard <pmezard@gmail.com>
Mon, 11 Jan 2010 21:15:53 +0100
changeset 10234 c8d6f339bbd7
parent 10230 9f0c7be7c46c
child 10236 49a8625b8cac
permissions -rwxr-xr-x
shrink-revlog: make it work on windows (issue1976)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     1
#!/usr/bin/env python
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     2
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
     3
"""\
10216
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
     4
Reorder a revlog (by default the manifest file in the current repository) to
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
     5
save space. Specifically, this topologically sorts the revisions in the revlog
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
     6
so that revisions on the same branch are adjacent as much as possible. This is
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
     7
a workaround for the fact that Mercurial computes deltas relative to the
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
     8
previous revision rather than relative to a parent revision.
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
     9
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
    10
This is *not* safe to run on a changelog.
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    11
"""
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    12
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    13
# Originally written by Benoit Boissinot <benoit.boissinot at ens-lyon.org>
10216
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
    14
# as a patch to rewrite-log. Cleaned up, refactored, documented, and
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    15
# renamed by Greg Ward <greg at gerg.ca>.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    16
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    17
# XXX would be nice to have a way to verify the repository after shrinking,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    18
# e.g. by comparing "before" and "after" states of random changesets
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    19
# (maybe: export before, shrink, export after, diff).
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    20
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    21
import sys, os, tempfile
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    22
import optparse
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    23
from mercurial import ui as ui_, hg, revlog, transaction, node, util
10009
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    24
from mercurial import changegroup
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    25
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    26
def toposort(ui, rl):
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    27
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    28
    children = {}
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    29
    root = []
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    30
    # build children and roots
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    31
    ui.write('reading %d revs ' % len(rl))
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    32
    try:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    33
        for i in rl:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    34
            children[i] = []
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    35
            parents = [p for p in rl.parentrevs(i) if p != node.nullrev]
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    36
            # in case of duplicate parents
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    37
            if len(parents) == 2 and parents[0] == parents[1]:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    38
                del parents[1]
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    39
            for p in parents:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    40
                assert p in children
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    41
                children[p].append(i)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    42
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    43
            if len(parents) == 0:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    44
                root.append(i)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    45
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    46
            if i % 1000 == 0:
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    47
                ui.write('.')
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    48
    finally:
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    49
        ui.write('\n')
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    50
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    51
    # XXX this is a reimplementation of the 'branchsort' topo sort
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    52
    # algorithm in hgext.convert.convcmd... would be nice not to duplicate
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    53
    # the algorithm
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    54
    ui.write('sorting ...')
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    55
    visit = root
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    56
    ret = []
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    57
    while visit:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    58
        i = visit.pop(0)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    59
        ret.append(i)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    60
        if i not in children:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    61
            # This only happens if some node's p1 == p2, which can
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    62
            # happen in the manifest in certain circumstances.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    63
            continue
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    64
        next = []
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    65
        for c in children.pop(i):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    66
            parents_unseen = [p for p in rl.parentrevs(c)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    67
                              if p != node.nullrev and p in children]
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    68
            if len(parents_unseen) == 0:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    69
                next.append(c)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    70
        visit = next + visit
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    71
    ui.write('\n')
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    72
    return ret
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    73
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    74
def writerevs(ui, r1, r2, order, tr):
10009
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    75
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    76
    ui.write('writing %d revs ' % len(order))
10009
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    77
    count = [0]
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    78
    def progress(*args):
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    79
        if count[0] % 1000 == 0:
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    80
            ui.write('.')
10009
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    81
        count[0] += 1
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    82
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    83
    order = [r1.node(r) for r in order]
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    84
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    85
    # this is a bit ugly, but it works
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    86
    lookup = lambda x: "%020d" % r1.linkrev(r1.rev(x))
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    87
    unlookup = lambda x: int(x, 10)
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    88
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    89
    try:
10009
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    90
        group = util.chunkbuffer(r1.group(order, lookup, progress))
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    91
        chunkiter = changegroup.chunkiter(group)
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
    92
        r2.addgroup(chunkiter, unlookup, tr)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    93
    finally:
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    94
        ui.write('\n')
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    95
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
    96
def report(ui, olddatafn, newdatafn):
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    97
    oldsize = float(os.stat(olddatafn).st_size)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    98
    newsize = float(os.stat(newdatafn).st_size)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
    99
9712
18b134ef294c kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9515
diff changeset
   100
    # argh: have to pass an int to %d, because a float >= 2^32
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   101
    # blows up under Python 2.5 or earlier
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   102
    ui.write('old file size: %12d bytes (%6.1f MiB)\n'
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   103
             % (int(oldsize), oldsize/1024/1024))
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   104
    ui.write('new file size: %12d bytes (%6.1f MiB)\n'
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   105
             % (int(newsize), newsize/1024/1024))
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   106
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   107
    shrink_percent = (oldsize - newsize) / oldsize * 100
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   108
    shrink_factor = oldsize / newsize
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   109
    ui.write('shrinkage: %.1f%% (%.1fx)\n' % (shrink_percent, shrink_factor))
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   110
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   111
def shrink(ui, repo, **opts):
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   112
    """
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   113
    Shrink revlog by re-ordering revisions. Will operate on manifest for
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   114
    the given repository if no other revlog is specified."""
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   115
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   116
    # Unbuffer stdout for nice progress output.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   117
    sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   118
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   119
    if not repo.local():
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   120
        raise util.Abort('not a local repository: %s' % repo.root)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   121
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   122
    fn = opts.get('revlog')
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   123
    if not fn:
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   124
        indexfn = repo.sjoin('00manifest.i')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   125
    else:
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   126
        if not fn.endswith('.i'):
10214
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   127
            raise util.Abort('--revlog option must specify the revlog index '
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   128
                             'file (*.i), not %s' % opts.get('revlog'))
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   129
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   130
        indexfn = os.path.realpath(fn)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   131
        store = repo.sjoin('')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   132
        if not indexfn.startswith(store):
10214
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   133
            raise util.Abort('--revlog option must specify a revlog in %s, '
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   134
                             'not %s' % (store, indexfn))
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   135
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   136
    datafn = indexfn[:-2] + '.d'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   137
    if not os.path.exists(indexfn):
10214
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   138
        raise util.Abort('no such file: %s' % indexfn)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   139
    if '00changelog' in indexfn:
10214
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   140
        raise util.Abort('shrinking the changelog will corrupt your repository')
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   141
    if not os.path.exists(datafn):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   142
        # This is just a lazy shortcut because I can't be bothered to
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   143
        # handle all the special cases that entail from no .d file.
10214
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   144
        raise util.Abort('%s does not exist: revlog not big enough '
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   145
                         'to be worth shrinking' % datafn)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   146
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   147
    oldindexfn = indexfn + '.old'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   148
    olddatafn = datafn + '.old'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   149
    if os.path.exists(oldindexfn) or os.path.exists(olddatafn):
10214
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   150
        raise util.Abort('one or both of\n'
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   151
                         '  %s\n'
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   152
                         '  %s\n'
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   153
                         'exists from a previous run; please clean up before '
8111f9988c9d contrib: fix error handling in shrink-revlog.py to be more hg-like
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10213
diff changeset
   154
                         'running again' % (oldindexfn, olddatafn))
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   155
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   156
    ui.write('shrinking %s\n' % indexfn)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   157
    prefix = os.path.basename(indexfn)[:-1]
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   158
    (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn),
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   159
                                           prefix=prefix,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   160
                                           suffix='.i')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   161
    tmpdatafn = tmpindexfn[:-2] + '.d'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   162
    os.close(tmpfd)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   163
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   164
    r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), indexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   165
    r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), tmpindexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   166
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   167
    # Don't use repo.transaction(), because then things get hairy with
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   168
    # paths: some need to be relative to .hg, and some need to be
10216
843f6ee6d14b contrib: small documentation fixes in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10215
diff changeset
   169
    # absolute. Doing it this way keeps things simple: everything is an
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   170
    # absolute path.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   171
    lock = repo.lock(wait=False)
10234
c8d6f339bbd7 shrink-revlog: make it work on windows (issue1976)
Patrick Mezard <pmezard@gmail.com>
parents: 10230
diff changeset
   172
    tr = transaction.transaction(ui.warn,
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   173
                                 open,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   174
                                 repo.sjoin('journal'))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   175
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   176
    try:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   177
        try:
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   178
            order = toposort(ui, r1)
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   179
            writerevs(ui, r1, r2, order, tr)
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   180
            report(ui, datafn, tmpdatafn)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   181
            tr.close()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   182
        except:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   183
            # Abort transaction first, so we truncate the files before
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   184
            # deleting them.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   185
            tr.abort()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   186
            if os.path.exists(tmpindexfn):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   187
                os.unlink(tmpindexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   188
            if os.path.exists(tmpdatafn):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   189
                os.unlink(tmpdatafn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   190
            raise
10234
c8d6f339bbd7 shrink-revlog: make it work on windows (issue1976)
Patrick Mezard <pmezard@gmail.com>
parents: 10230
diff changeset
   191
        # Racy since both files cannot be renamed atomically
c8d6f339bbd7 shrink-revlog: make it work on windows (issue1976)
Patrick Mezard <pmezard@gmail.com>
parents: 10230
diff changeset
   192
        util.os_link(indexfn, oldindexfn)
c8d6f339bbd7 shrink-revlog: make it work on windows (issue1976)
Patrick Mezard <pmezard@gmail.com>
parents: 10230
diff changeset
   193
        util.os_link(datafn, olddatafn)
c8d6f339bbd7 shrink-revlog: make it work on windows (issue1976)
Patrick Mezard <pmezard@gmail.com>
parents: 10230
diff changeset
   194
        util.rename(tmpindexfn, indexfn)
c8d6f339bbd7 shrink-revlog: make it work on windows (issue1976)
Patrick Mezard <pmezard@gmail.com>
parents: 10230
diff changeset
   195
        util.rename(tmpdatafn, datafn)
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   196
    finally:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   197
        lock.release()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   198
10213
9e6848f352b0 contrib: use ui to write in shrink-revlog.py
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10009
diff changeset
   199
    ui.write('note: old revlog saved in:\n'
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   200
          '  %s\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   201
          '  %s\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   202
          '(You can delete those files when you are satisfied that your\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   203
          'repository is still sane.  '
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   204
          'Running \'hg verify\' is strongly recommended.)\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   205
          % (oldindexfn, olddatafn))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
   206
10215
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   207
cmdtable = {
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   208
    'shrink': (shrink,
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   209
               [('', 'revlog', '', 'shrink file')],
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   210
               'hg shrink [--revlog PATH]')
9d79b8f58bea contrib: turn shrink-revlog.py into an extension
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 10214
diff changeset
   211
}