##// END OF EJS Templates
merge with default
Benoit Boissinot -
r10543:dd352616 merge stable
parent child Browse files
Show More
@@ -19,7 +19,7 b' This is *not* safe to run on a changelog'
19 # e.g. by comparing "before" and "after" states of random changesets
19 # e.g. by comparing "before" and "after" states of random changesets
20 # (maybe: export before, shrink, export after, diff).
20 # (maybe: export before, shrink, export after, diff).
21
21
22 import os, tempfile
22 import os, tempfile, errno
23 from mercurial import revlog, transaction, node, util
23 from mercurial import revlog, transaction, node, util
24 from mercurial import changegroup
24 from mercurial import changegroup
25 from mercurial.i18n import _
25 from mercurial.i18n import _
@@ -91,9 +91,19 b' def writerevs(ui, r1, r2, order, tr):'
91 finally:
91 finally:
92 ui.progress(_('writing'), None, len(order))
92 ui.progress(_('writing'), None, len(order))
93
93
94 def report(ui, olddatafn, newdatafn):
94 def report(ui, r1, r2):
95 oldsize = float(os.stat(olddatafn).st_size)
95 def getsize(r):
96 newsize = float(os.stat(newdatafn).st_size)
96 s = 0
97 for fn in (r.indexfile, r.datafile):
98 try:
99 s += os.stat(fn).st_size
100 except OSError, inst:
101 if inst.errno != errno.ENOENT:
102 raise
103 return s
104
105 oldsize = float(getsize(r1))
106 newsize = float(getsize(r2))
97
107
98 # argh: have to pass an int to %d, because a float >= 2^32
108 # argh: have to pass an int to %d, because a float >= 2^32
99 # blows up under Python 2.5 or earlier
109 # blows up under Python 2.5 or earlier
@@ -129,17 +139,23 b' def shrink(ui, repo, **opts):'
129 raise util.Abort(_('--revlog option must specify a revlog in %s, '
139 raise util.Abort(_('--revlog option must specify a revlog in %s, '
130 'not %s') % (store, indexfn))
140 'not %s') % (store, indexfn))
131
141
132 datafn = indexfn[:-2] + '.d'
133 if not os.path.exists(indexfn):
142 if not os.path.exists(indexfn):
134 raise util.Abort(_('no such file: %s') % indexfn)
143 raise util.Abort(_('no such file: %s') % indexfn)
135 if '00changelog' in indexfn:
144 if '00changelog' in indexfn:
136 raise util.Abort(_('shrinking the changelog '
145 raise util.Abort(_('shrinking the changelog '
137 'will corrupt your repository'))
146 'will corrupt your repository'))
138 if not os.path.exists(datafn):
147
139 # This is just a lazy shortcut because I can't be bothered to
148 ui.write(_('shrinking %s\n') % indexfn)
140 # handle all the special cases that entail from no .d file.
149 prefix = os.path.basename(indexfn)[:-1]
141 raise util.Abort(_('%s does not exist: revlog not big enough '
150 (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn),
142 'to be worth shrinking') % datafn)
151 prefix=prefix,
152 suffix='.i')
153 os.close(tmpfd)
154
155 r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), indexfn)
156 r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), tmpindexfn)
157
158 datafn, tmpdatafn = r1.datafile, r2.datafile
143
159
144 oldindexfn = indexfn + '.old'
160 oldindexfn = indexfn + '.old'
145 olddatafn = datafn + '.old'
161 olddatafn = datafn + '.old'
@@ -150,17 +166,6 b' def shrink(ui, repo, **opts):'
150 'exists from a previous run; please clean up '
166 'exists from a previous run; please clean up '
151 'before running again') % (oldindexfn, olddatafn))
167 'before running again') % (oldindexfn, olddatafn))
152
168
153 ui.write(_('shrinking %s\n') % indexfn)
154 prefix = os.path.basename(indexfn)[:-1]
155 (tmpfd, tmpindexfn) = tempfile.mkstemp(dir=os.path.dirname(indexfn),
156 prefix=prefix,
157 suffix='.i')
158 tmpdatafn = tmpindexfn[:-2] + '.d'
159 os.close(tmpfd)
160
161 r1 = revlog.revlog(util.opener(os.getcwd(), audit=False), indexfn)
162 r2 = revlog.revlog(util.opener(os.getcwd(), audit=False), tmpindexfn)
163
164 # Don't use repo.transaction(), because then things get hairy with
169 # Don't use repo.transaction(), because then things get hairy with
165 # paths: some need to be relative to .hg, and some need to be
170 # paths: some need to be relative to .hg, and some need to be
166 # absolute. Doing it this way keeps things simple: everything is an
171 # absolute. Doing it this way keeps things simple: everything is an
@@ -170,30 +175,44 b' def shrink(ui, repo, **opts):'
170 open,
175 open,
171 repo.sjoin('journal'))
176 repo.sjoin('journal'))
172
177
178 def ignoremissing(func):
179 def f(*args, **kw):
180 try:
181 return func(*args, **kw)
182 except OSError, inst:
183 if inst.errno != errno.ENOENT:
184 raise
185 return f
186
173 try:
187 try:
174 try:
188 try:
175 order = toposort(ui, r1)
189 order = toposort(ui, r1)
176 writerevs(ui, r1, r2, order, tr)
190 writerevs(ui, r1, r2, order, tr)
177 report(ui, datafn, tmpdatafn)
191 report(ui, r1, r2)
178 tr.close()
192 tr.close()
179 except:
193 except:
180 # Abort transaction first, so we truncate the files before
194 # Abort transaction first, so we truncate the files before
181 # deleting them.
195 # deleting them.
182 tr.abort()
196 tr.abort()
183 if os.path.exists(tmpindexfn):
197 for fn in (tmpindexfn, tmpdatafn):
184 os.unlink(tmpindexfn)
198 ignoremissing(os.unlink)(fn)
185 if os.path.exists(tmpdatafn):
186 os.unlink(tmpdatafn)
187 raise
199 raise
188 if not opts.get('dry_run'):
200 if not opts.get('dry_run'):
189 # Racy since both files cannot be renamed atomically
201 # racy, both files cannot be renamed atomically
202 # copy files
190 util.os_link(indexfn, oldindexfn)
203 util.os_link(indexfn, oldindexfn)
191 util.os_link(datafn, olddatafn)
204 ignoremissing(util.os_link)(datafn, olddatafn)
205 # rename
192 util.rename(tmpindexfn, indexfn)
206 util.rename(tmpindexfn, indexfn)
193 util.rename(tmpdatafn, datafn)
207 try:
208 util.rename(tmpdatafn, datafn)
209 except OSError, inst:
210 if inst.errno != errno.ENOENT:
211 raise
212 ignoremissing(os.unlink)(datafn)
194 else:
213 else:
195 os.unlink(tmpindexfn)
214 for fn in (tmpindexfn, tmpdatafn):
196 os.unlink(tmpdatafn)
215 ignoremissing(os.unlink)(fn)
197 finally:
216 finally:
198 lock.release()
217 lock.release()
199
218
@@ -6,7 +6,7 b''
6 '''commands to sign and verify changesets'''
6 '''commands to sign and verify changesets'''
7
7
8 import os, tempfile, binascii
8 import os, tempfile, binascii
9 from mercurial import util, commands, match, cmdutil
9 from mercurial import util, commands, match
10 from mercurial import node as hgnode
10 from mercurial import node as hgnode
11 from mercurial.i18n import _
11 from mercurial.i18n import _
12
12
@@ -237,7 +237,7 b' def sign(ui, repo, *revs, **opts):'
237 repo.opener("localsigs", "ab").write(sigmessage)
237 repo.opener("localsigs", "ab").write(sigmessage)
238 return
238 return
239
239
240 msigs = cmdutil.matchfiles(repo, ['.hgsigs'])
240 msigs = match.exact(repo.root, '', ['.hgsigs'])
241 s = repo.status(match=msigs, unknown=True, ignored=True)[:6]
241 s = repo.status(match=msigs, unknown=True, ignored=True)[:6]
242 if util.any(s) and not opts["force"]:
242 if util.any(s) and not opts["force"]:
243 raise util.Abort(_("working copy of .hgsigs is changed "
243 raise util.Abort(_("working copy of .hgsigs is changed "
General Comments 0
You need to be logged in to leave comments. Login now