annotate contrib/shrink-revlog.py @ 10009:69dca8574a6a

shrink-revlog: improve performance: use changegroup instead of revisions Before: real 0m23.971s Now: real 0m4.229s The only case where the output would be different is if the newer hg was using a different diff algorithm than used originally.
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Fri, 04 Dec 2009 15:36:13 +0100
parents 18b134ef294c
children 9e6848f352b0
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
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 """\
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
4 Reorder a revlog (by default the the manifest file in the current
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
5 repository) to save space. Specifically, this topologically sorts the
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
6 revisions in the revlog so that revisions on the same branch are adjacent
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
7 as much as possible. This is a workaround for the fact that Mercurial
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
8 computes deltas relative to the previous revision rather than relative to a
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
9 parent revision. This is *not* safe to run on a changelog.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
10 """
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 # Originally written by Benoit Boissinot <benoit.boissinot at ens-lyon.org>
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
13 # as a patch to rewrite-log. Cleaned up, refactored, documented, and
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
14 # 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
15
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
16 # 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
17 # 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
18 # (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
19
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
20 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
21 import optparse
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
22 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
23 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
24
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
25 def toposort(rl):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
26 write = sys.stdout.write
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
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
31 write('reading %d revs ' % len(rl))
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:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
47 write('.')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
48 finally:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
49 write('\n')
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
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
54 write('sorting ...')
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
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
71 write('\n')
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
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
74 def writerevs(r1, r2, order, tr):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
75 write = sys.stdout.write
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
76 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
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
78 count = [0]
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
79 def progress(*args):
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
80 if count[0] % 1000 == 0:
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
81 write('.')
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
82 count[0] += 1
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
83
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
84 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
85
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
86 # 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
87 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
88 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
89
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
90 try:
10009
69dca8574a6a shrink-revlog: improve performance: use changegroup instead of revisions
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 9712
diff changeset
91 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
92 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
93 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
94 finally:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
95 write('\n')
9712
18b134ef294c kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9515
diff changeset
96
9515
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
97 def report(olddatafn, newdatafn):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
98 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
99 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
100
9712
18b134ef294c kill trailing whitespace
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 9515
diff changeset
101 # 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
102 # blows up under Python 2.5 or earlier
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
103 sys.stdout.write('old file size: %12d bytes (%6.1f MiB)\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
104 % (int(oldsize), oldsize/1024/1024))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
105 sys.stdout.write('new file size: %12d bytes (%6.1f MiB)\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
106 % (int(newsize), newsize/1024/1024))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
107
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
108 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
109 shrink_factor = oldsize / newsize
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
110 sys.stdout.write('shrinkage: %.1f%% (%.1fx)\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
111 % (shrink_percent, shrink_factor))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
112
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
113 def main():
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
114
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
115 # 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
116 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
117 write = sys.stdout.write
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
118
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
119 parser = optparse.OptionParser(description=__doc__)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
120 parser.add_option('-R', '--repository',
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
121 default=os.path.curdir,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
122 metavar='REPO',
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
123 help='repository root directory [default: current dir]')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
124 parser.add_option('--revlog',
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
125 metavar='FILE',
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
126 help='shrink FILE [default: REPO/hg/store/00manifest.i]')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
127 (options, args) = parser.parse_args()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
128 if args:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
129 parser.error('too many arguments')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
130
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
131 # Open the specified repository.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
132 ui = ui_.ui()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
133 repo = hg.repository(ui, options.repository)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
134 if not repo.local():
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
135 parser.error('not a local repository: %s' % options.repository)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
136
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
137 if options.revlog is None:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
138 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
139 else:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
140 if not options.revlog.endswith('.i'):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
141 parser.error('--revlog option must specify the revlog index file '
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
142 '(*.i), not %s' % options.revlog)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
143
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
144 indexfn = os.path.realpath(options.revlog)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
145 store = repo.sjoin('')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
146 if not indexfn.startswith(store):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
147 parser.error('--revlog option must specify a revlog in %s, not %s'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
148 % (store, indexfn))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
149
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
150 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
151 if not os.path.exists(indexfn):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
152 parser.error('no such file: %s' % indexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
153 if '00changelog' in indexfn:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
154 parser.error('shrinking the changelog will corrupt your repository')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
155 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
156 # 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
157 # handle all the special cases that entail from no .d file.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
158 parser.error('%s does not exist: revlog not big enough '
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
159 'to be worth shrinking' % datafn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
160
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
161 oldindexfn = indexfn + '.old'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
162 olddatafn = datafn + '.old'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
163 if os.path.exists(oldindexfn) or os.path.exists(olddatafn):
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
164 parser.error('one or both of\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
165 ' %s\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
166 ' %s\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
167 'exists from a previous run; please clean up before '
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
168 'running again'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
169 % (oldindexfn, olddatafn))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
170
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
171 write('shrinking %s\n' % indexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
172 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
173 (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
174 prefix=prefix,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
175 suffix='.i')
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
176 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
177 os.close(tmpfd)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
178
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
179 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
180 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
181
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
182 # 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
183 # paths: some need to be relative to .hg, and some need to be
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
184 # absolute. Doing it this way keeps things simple: everything is an
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
185 # absolute path.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
186 lock = repo.lock(wait=False)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
187 tr = transaction.transaction(sys.stderr.write,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
188 open,
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
189 repo.sjoin('journal'))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
190
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
191 try:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
192 try:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
193 order = toposort(r1)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
194 writerevs(r1, r2, order, tr)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
195 report(datafn, tmpdatafn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
196 tr.close()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
197 except:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
198 # 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
199 # deleting them.
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
200 tr.abort()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
201 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
202 os.unlink(tmpindexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
203 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
204 os.unlink(tmpdatafn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
205 raise
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
206 finally:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
207 lock.release()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
208
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
209 os.link(indexfn, oldindexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
210 os.link(datafn, olddatafn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
211 os.rename(tmpindexfn, indexfn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
212 os.rename(tmpdatafn, datafn)
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
213 write('note: old revlog saved in:\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
214 ' %s\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
215 ' %s\n'
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
216 '(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
217 '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
218 '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
219 % (oldindexfn, olddatafn))
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
220
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
221 try:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
222 main()
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
223 except KeyboardInterrupt:
f7d85980261c Add script to rewrite revlog to workaround lack of parent deltas.
Greg Ward <greg-hg@gerg.ca>
parents:
diff changeset
224 sys.exit("interrupted")