##// END OF EJS Templates
repair: fix typo in warning message
Wagner Bruna -
r25874:3e84f402 stable
parent child Browse files
Show More
@@ -1,298 +1,298 b''
1 1 # repair.py - functions for repository repair for mercurial
2 2 #
3 3 # Copyright 2005, 2006 Chris Mason <mason@suse.com>
4 4 # Copyright 2007 Matt Mackall
5 5 #
6 6 # This software may be used and distributed according to the terms of the
7 7 # GNU General Public License version 2 or any later version.
8 8
9 9 from mercurial import changegroup, exchange, util, bundle2
10 10 from mercurial.node import short
11 11 from mercurial.i18n import _
12 12 import errno
13 13
14 14 def _bundle(repo, bases, heads, node, suffix, compress=True):
15 15 """create a bundle with the specified revisions as a backup"""
16 16 usebundle2 = (repo.ui.configbool('experimental', 'bundle2-exp', True) and
17 17 repo.ui.config('experimental', 'strip-bundle2-version'))
18 18 if usebundle2:
19 19 cgversion = repo.ui.config('experimental', 'strip-bundle2-version')
20 20 if cgversion not in changegroup.packermap:
21 21 repo.ui.warn(_('unknown strip-bundle2-version value %r; '
22 22 'should be one of %r\n') %
23 23 (cgversion, sorted(changegroup.packermap.keys()),))
24 24 cgversion = '01'
25 25 usebundle2 = False
26 26 else:
27 27 cgversion = '01'
28 28
29 29 cg = changegroup.changegroupsubset(repo, bases, heads, 'strip',
30 30 version=cgversion)
31 31 backupdir = "strip-backup"
32 32 vfs = repo.vfs
33 33 if not vfs.isdir(backupdir):
34 34 vfs.mkdir(backupdir)
35 35
36 36 # Include a hash of all the nodes in the filename for uniqueness
37 37 allcommits = repo.set('%ln::%ln', bases, heads)
38 38 allhashes = sorted(c.hex() for c in allcommits)
39 39 totalhash = util.sha1(''.join(allhashes)).hexdigest()
40 40 name = "%s/%s-%s-%s.hg" % (backupdir, short(node), totalhash[:8], suffix)
41 41
42 42 if usebundle2:
43 43 bundletype = "HG20"
44 44 elif compress:
45 45 bundletype = "HG10BZ"
46 46 else:
47 47 bundletype = "HG10UN"
48 48 return changegroup.writebundle(repo.ui, cg, name, bundletype, vfs)
49 49
50 50 def _collectfiles(repo, striprev):
51 51 """find out the filelogs affected by the strip"""
52 52 files = set()
53 53
54 54 for x in xrange(striprev, len(repo)):
55 55 files.update(repo[x].files())
56 56
57 57 return sorted(files)
58 58
59 59 def _collectbrokencsets(repo, files, striprev):
60 60 """return the changesets which will be broken by the truncation"""
61 61 s = set()
62 62 def collectone(revlog):
63 63 _, brokenset = revlog.getstrippoint(striprev)
64 64 s.update([revlog.linkrev(r) for r in brokenset])
65 65
66 66 collectone(repo.manifest)
67 67 for fname in files:
68 68 collectone(repo.file(fname))
69 69
70 70 return s
71 71
72 72 def strip(ui, repo, nodelist, backup=True, topic='backup'):
73 73
74 74 # Simple way to maintain backwards compatibility for this
75 75 # argument.
76 76 if backup in ['none', 'strip']:
77 77 backup = False
78 78
79 79 repo = repo.unfiltered()
80 80 repo.destroying()
81 81
82 82 cl = repo.changelog
83 83 # TODO handle undo of merge sets
84 84 if isinstance(nodelist, str):
85 85 nodelist = [nodelist]
86 86 striplist = [cl.rev(node) for node in nodelist]
87 87 striprev = min(striplist)
88 88
89 89 # Some revisions with rev > striprev may not be descendants of striprev.
90 90 # We have to find these revisions and put them in a bundle, so that
91 91 # we can restore them after the truncations.
92 92 # To create the bundle we use repo.changegroupsubset which requires
93 93 # the list of heads and bases of the set of interesting revisions.
94 94 # (head = revision in the set that has no descendant in the set;
95 95 # base = revision in the set that has no ancestor in the set)
96 96 tostrip = set(striplist)
97 97 for rev in striplist:
98 98 for desc in cl.descendants([rev]):
99 99 tostrip.add(desc)
100 100
101 101 files = _collectfiles(repo, striprev)
102 102 saverevs = _collectbrokencsets(repo, files, striprev)
103 103
104 104 # compute heads
105 105 saveheads = set(saverevs)
106 106 for r in xrange(striprev + 1, len(cl)):
107 107 if r not in tostrip:
108 108 saverevs.add(r)
109 109 saveheads.difference_update(cl.parentrevs(r))
110 110 saveheads.add(r)
111 111 saveheads = [cl.node(r) for r in saveheads]
112 112
113 113 # compute base nodes
114 114 if saverevs:
115 115 descendants = set(cl.descendants(saverevs))
116 116 saverevs.difference_update(descendants)
117 117 savebases = [cl.node(r) for r in saverevs]
118 118 stripbases = [cl.node(r) for r in tostrip]
119 119
120 120 # For a set s, max(parents(s) - s) is the same as max(heads(::s - s)), but
121 121 # is much faster
122 122 newbmtarget = repo.revs('max(parents(%ld) - (%ld))', tostrip, tostrip)
123 123 if newbmtarget:
124 124 newbmtarget = repo[newbmtarget.first()].node()
125 125 else:
126 126 newbmtarget = '.'
127 127
128 128 bm = repo._bookmarks
129 129 updatebm = []
130 130 for m in bm:
131 131 rev = repo[bm[m]].rev()
132 132 if rev in tostrip:
133 133 updatebm.append(m)
134 134
135 135 # create a changegroup for all the branches we need to keep
136 136 backupfile = None
137 137 vfs = repo.vfs
138 138 node = nodelist[-1]
139 139 if backup:
140 140 backupfile = _bundle(repo, stripbases, cl.heads(), node, topic)
141 141 repo.ui.status(_("saved backup bundle to %s\n") %
142 142 vfs.join(backupfile))
143 143 repo.ui.log("backupbundle", "saved backup bundle to %s\n",
144 144 vfs.join(backupfile))
145 145 if saveheads or savebases:
146 146 # do not compress partial bundle if we remove it from disk later
147 147 chgrpfile = _bundle(repo, savebases, saveheads, node, 'temp',
148 148 compress=False)
149 149
150 150 mfst = repo.manifest
151 151
152 152 curtr = repo.currenttransaction()
153 153 if curtr is not None:
154 154 del curtr # avoid carrying reference to transaction for nothing
155 155 msg = _('programming error: cannot strip from inside a transaction')
156 156 raise util.Abort(msg, hint=_('contact your extension maintainer'))
157 157
158 158 tr = repo.transaction("strip")
159 159 offset = len(tr.entries)
160 160
161 161 try:
162 162 tr.startgroup()
163 163 cl.strip(striprev, tr)
164 164 mfst.strip(striprev, tr)
165 165 for fn in files:
166 166 repo.file(fn).strip(striprev, tr)
167 167 tr.endgroup()
168 168
169 169 try:
170 170 for i in xrange(offset, len(tr.entries)):
171 171 file, troffset, ignore = tr.entries[i]
172 172 repo.svfs(file, 'a').truncate(troffset)
173 173 if troffset == 0:
174 174 repo.store.markremoved(file)
175 175 tr.close()
176 176 except: # re-raises
177 177 tr.abort()
178 178 raise
179 179
180 180 if saveheads or savebases:
181 181 ui.note(_("adding branch\n"))
182 182 f = vfs.open(chgrpfile, "rb")
183 183 gen = exchange.readbundle(ui, f, chgrpfile, vfs)
184 184 if not repo.ui.verbose:
185 185 # silence internal shuffling chatter
186 186 repo.ui.pushbuffer()
187 187 if isinstance(gen, bundle2.unbundle20):
188 188 tr = repo.transaction('strip')
189 189 tr.hookargs = {'source': 'strip',
190 190 'url': 'bundle:' + vfs.join(chgrpfile)}
191 191 try:
192 192 bundle2.processbundle(repo, gen, lambda: tr)
193 193 tr.close()
194 194 finally:
195 195 tr.release()
196 196 else:
197 197 changegroup.addchangegroup(repo, gen, 'strip',
198 198 'bundle:' + vfs.join(chgrpfile),
199 199 True)
200 200 if not repo.ui.verbose:
201 201 repo.ui.popbuffer()
202 202 f.close()
203 203
204 204 # remove undo files
205 205 for undovfs, undofile in repo.undofiles():
206 206 try:
207 207 undovfs.unlink(undofile)
208 208 except OSError as e:
209 209 if e.errno != errno.ENOENT:
210 210 ui.warn(_('error removing %s: %s\n') %
211 211 (undovfs.join(undofile), str(e)))
212 212
213 213 for m in updatebm:
214 214 bm[m] = repo[newbmtarget].node()
215 215 bm.write()
216 216 except: # re-raises
217 217 if backupfile:
218 218 ui.warn(_("strip failed, full bundle stored in '%s'\n")
219 219 % vfs.join(backupfile))
220 220 elif saveheads:
221 221 ui.warn(_("strip failed, partial bundle stored in '%s'\n")
222 222 % vfs.join(chgrpfile))
223 223 raise
224 224 else:
225 225 if saveheads or savebases:
226 226 # Remove partial backup only if there were no exceptions
227 227 vfs.unlink(chgrpfile)
228 228
229 229 repo.destroyed()
230 230
231 231 def rebuildfncache(ui, repo):
232 232 """Rebuilds the fncache file from repo history.
233 233
234 234 Missing entries will be added. Extra entries will be removed.
235 235 """
236 236 repo = repo.unfiltered()
237 237
238 238 if 'fncache' not in repo.requirements:
239 239 ui.warn(_('(not rebuilding fncache because repository does not '
240 'support fncache\n'))
240 'support fncache)\n'))
241 241 return
242 242
243 243 lock = repo.lock()
244 244 try:
245 245 fnc = repo.store.fncache
246 246 # Trigger load of fncache.
247 247 if 'irrelevant' in fnc:
248 248 pass
249 249
250 250 oldentries = set(fnc.entries)
251 251 newentries = set()
252 252 seenfiles = set()
253 253
254 254 repolen = len(repo)
255 255 for rev in repo:
256 256 ui.progress(_('changeset'), rev, total=repolen)
257 257
258 258 ctx = repo[rev]
259 259 for f in ctx.files():
260 260 # This is to minimize I/O.
261 261 if f in seenfiles:
262 262 continue
263 263 seenfiles.add(f)
264 264
265 265 i = 'data/%s.i' % f
266 266 d = 'data/%s.d' % f
267 267
268 268 if repo.store._exists(i):
269 269 newentries.add(i)
270 270 if repo.store._exists(d):
271 271 newentries.add(d)
272 272
273 273 ui.progress(_('changeset'), None)
274 274
275 275 addcount = len(newentries - oldentries)
276 276 removecount = len(oldentries - newentries)
277 277 for p in sorted(oldentries - newentries):
278 278 ui.write(_('removing %s\n') % p)
279 279 for p in sorted(newentries - oldentries):
280 280 ui.write(_('adding %s\n') % p)
281 281
282 282 if addcount or removecount:
283 283 ui.write(_('%d items added, %d removed from fncache\n') %
284 284 (addcount, removecount))
285 285 fnc.entries = newentries
286 286 fnc._dirty = True
287 287
288 288 tr = repo.transaction('fncache')
289 289 try:
290 290 fnc.write(tr)
291 291 tr.close()
292 292 finally:
293 293 tr.release()
294 294 else:
295 295 ui.write(_('fncache already up to date\n'))
296 296 finally:
297 297 lock.release()
298 298
@@ -1,397 +1,397 b''
1 1 Init repo1:
2 2
3 3 $ hg init repo1
4 4 $ cd repo1
5 5 $ echo "some text" > a
6 6 $ hg add
7 7 adding a
8 8 $ hg ci -m first
9 9 $ cat .hg/store/fncache | sort
10 10 data/a.i
11 11
12 12 Testing a.i/b:
13 13
14 14 $ mkdir a.i
15 15 $ echo "some other text" > a.i/b
16 16 $ hg add
17 17 adding a.i/b (glob)
18 18 $ hg ci -m second
19 19 $ cat .hg/store/fncache | sort
20 20 data/a.i
21 21 data/a.i.hg/b.i
22 22
23 23 Testing a.i.hg/c:
24 24
25 25 $ mkdir a.i.hg
26 26 $ echo "yet another text" > a.i.hg/c
27 27 $ hg add
28 28 adding a.i.hg/c (glob)
29 29 $ hg ci -m third
30 30 $ cat .hg/store/fncache | sort
31 31 data/a.i
32 32 data/a.i.hg.hg/c.i
33 33 data/a.i.hg/b.i
34 34
35 35 Testing verify:
36 36
37 37 $ hg verify
38 38 checking changesets
39 39 checking manifests
40 40 crosschecking files in changesets and manifests
41 41 checking files
42 42 3 files, 3 changesets, 3 total revisions
43 43
44 44 $ rm .hg/store/fncache
45 45
46 46 $ hg verify
47 47 checking changesets
48 48 checking manifests
49 49 crosschecking files in changesets and manifests
50 50 checking files
51 51 warning: revlog 'data/a.i' not in fncache!
52 52 warning: revlog 'data/a.i.hg/c.i' not in fncache!
53 53 warning: revlog 'data/a.i/b.i' not in fncache!
54 54 3 files, 3 changesets, 3 total revisions
55 55 3 warnings encountered!
56 56 hint: run "hg debugrebuildfncache" to recover from corrupt fncache
57 57
58 58 Follow the hint to make sure it works
59 59
60 60 $ hg debugrebuildfncache
61 61 adding data/a.i
62 62 adding data/a.i.hg/c.i
63 63 adding data/a.i/b.i
64 64 3 items added, 0 removed from fncache
65 65
66 66 $ hg verify
67 67 checking changesets
68 68 checking manifests
69 69 crosschecking files in changesets and manifests
70 70 checking files
71 71 3 files, 3 changesets, 3 total revisions
72 72
73 73 $ cd ..
74 74
75 75 Non store repo:
76 76
77 77 $ hg --config format.usestore=False init foo
78 78 $ cd foo
79 79 $ mkdir tst.d
80 80 $ echo foo > tst.d/foo
81 81 $ hg ci -Amfoo
82 82 adding tst.d/foo
83 83 $ find .hg | sort
84 84 .hg
85 85 .hg/00changelog.i
86 86 .hg/00manifest.i
87 87 .hg/cache
88 88 .hg/cache/branch2-served
89 89 .hg/cache/rbc-names-v1
90 90 .hg/cache/rbc-revs-v1
91 91 .hg/data
92 92 .hg/data/tst.d.hg
93 93 .hg/data/tst.d.hg/foo.i
94 94 .hg/dirstate
95 95 .hg/last-message.txt
96 96 .hg/phaseroots
97 97 .hg/requires
98 98 .hg/undo
99 99 .hg/undo.backupfiles
100 100 .hg/undo.bookmarks
101 101 .hg/undo.branch
102 102 .hg/undo.desc
103 103 .hg/undo.dirstate
104 104 .hg/undo.phaseroots
105 105 $ cd ..
106 106
107 107 Non fncache repo:
108 108
109 109 $ hg --config format.usefncache=False init bar
110 110 $ cd bar
111 111 $ mkdir tst.d
112 112 $ echo foo > tst.d/Foo
113 113 $ hg ci -Amfoo
114 114 adding tst.d/Foo
115 115 $ find .hg | sort
116 116 .hg
117 117 .hg/00changelog.i
118 118 .hg/cache
119 119 .hg/cache/branch2-served
120 120 .hg/cache/rbc-names-v1
121 121 .hg/cache/rbc-revs-v1
122 122 .hg/dirstate
123 123 .hg/last-message.txt
124 124 .hg/requires
125 125 .hg/store
126 126 .hg/store/00changelog.i
127 127 .hg/store/00manifest.i
128 128 .hg/store/data
129 129 .hg/store/data/tst.d.hg
130 130 .hg/store/data/tst.d.hg/_foo.i
131 131 .hg/store/phaseroots
132 132 .hg/store/undo
133 133 .hg/store/undo.backupfiles
134 134 .hg/store/undo.phaseroots
135 135 .hg/undo.bookmarks
136 136 .hg/undo.branch
137 137 .hg/undo.desc
138 138 .hg/undo.dirstate
139 139 $ cd ..
140 140
141 141 Encoding of reserved / long paths in the store
142 142
143 143 $ hg init r2
144 144 $ cd r2
145 145 $ cat <<EOF > .hg/hgrc
146 146 > [ui]
147 147 > portablefilenames = ignore
148 148 > EOF
149 149
150 150 $ hg import -q --bypass - <<EOF
151 151 > # HG changeset patch
152 152 > # User test
153 153 > # Date 0 0
154 154 > # Node ID 1c7a2f7cb77be1a0def34e4c7cabc562ad98fbd7
155 155 > # Parent 0000000000000000000000000000000000000000
156 156 > 1
157 157 >
158 158 > diff --git a/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
159 159 > new file mode 100644
160 160 > --- /dev/null
161 161 > +++ b/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxxxxx-xxxxxxxxx-xxxxxxxxx-123456789-12.3456789-12345-ABCDEFGHIJKLMNOPRSTUVWXYZ-abcdefghjiklmnopqrstuvwxyz
162 162 > @@ -0,0 +1,1 @@
163 163 > +foo
164 164 > diff --git a/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
165 165 > new file mode 100644
166 166 > --- /dev/null
167 167 > +++ b/AUX/SECOND/X.PRN/FOURTH/FI:FTH/SIXTH/SEVENTH/EIGHTH/NINETH/TENTH/ELEVENTH/LOREMIPSUM.TXT
168 168 > @@ -0,0 +1,1 @@
169 169 > +foo
170 170 > diff --git a/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
171 171 > new file mode 100644
172 172 > --- /dev/null
173 173 > +++ b/Project Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt
174 174 > @@ -0,0 +1,1 @@
175 175 > +foo
176 176 > diff --git a/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
177 177 > new file mode 100644
178 178 > --- /dev/null
179 179 > +++ b/bla.aux/prn/PRN/lpt/com3/nul/coma/foo.NUL/normal.c
180 180 > @@ -0,0 +1,1 @@
181 181 > +foo
182 182 > diff --git a/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
183 183 > new file mode 100644
184 184 > --- /dev/null
185 185 > +++ b/enterprise/openesbaddons/contrib-imola/corba-bc/netbeansplugin/wsdlExtension/src/main/java/META-INF/services/org.netbeans.modules.xml.wsdl.bindingsupport.spi.ExtensibilityElementTemplateProvider
186 186 > @@ -0,0 +1,1 @@
187 187 > +foo
188 188 > EOF
189 189
190 190 $ find .hg/store -name *.i | sort
191 191 .hg/store/00changelog.i
192 192 .hg/store/00manifest.i
193 193 .hg/store/data/bla.aux/pr~6e/_p_r_n/lpt/co~6d3/nu~6c/coma/foo._n_u_l/normal.c.i
194 194 .hg/store/dh/12345678/12345678/12345678/12345678/12345678/12345678/12345678/12345/xxxxxx168e07b38e65eff86ab579afaaa8e30bfbe0f35f.i
195 195 .hg/store/dh/au~78/second/x.prn/fourth/fi~3afth/sixth/seventh/eighth/nineth/tenth/loremia20419e358ddff1bf8751e38288aff1d7c32ec05.i
196 196 .hg/store/dh/enterpri/openesba/contrib-/corba-bc/netbeans/wsdlexte/src/main/java/org.net7018f27961fdf338a598a40c4683429e7ffb9743.i
197 197 .hg/store/dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilename0d8e1f4187c650e2f1fdca9fd90f786bc0976b6b.i
198 198
199 199 $ cd ..
200 200
201 201 Aborting lock does not prevent fncache writes
202 202
203 203 $ cat > exceptionext.py <<EOF
204 204 > import os
205 205 > from mercurial import commands, util
206 206 > from mercurial.extensions import wrapfunction
207 207 >
208 208 > def lockexception(orig, vfs, lockname, wait, releasefn, acquirefn, desc):
209 209 > def releasewrap():
210 210 > raise util.Abort("forced lock failure")
211 211 > return orig(vfs, lockname, wait, releasewrap, acquirefn, desc)
212 212 >
213 213 > def reposetup(ui, repo):
214 214 > wrapfunction(repo, '_lock', lockexception)
215 215 >
216 216 > cmdtable = {}
217 217 >
218 218 > EOF
219 219 $ extpath=`pwd`/exceptionext.py
220 220 $ hg init fncachetxn
221 221 $ cd fncachetxn
222 222 $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc
223 223 $ touch y
224 224 $ hg ci -qAm y
225 225 abort: forced lock failure
226 226 [255]
227 227 $ cat .hg/store/fncache
228 228 data/y.i
229 229
230 230 Aborting transaction prevents fncache change
231 231
232 232 $ cat > ../exceptionext.py <<EOF
233 233 > import os
234 234 > from mercurial import commands, util, localrepo
235 235 > from mercurial.extensions import wrapfunction
236 236 >
237 237 > def wrapper(orig, self, *args, **kwargs):
238 238 > tr = orig(self, *args, **kwargs)
239 239 > def fail(tr):
240 240 > raise util.Abort("forced transaction failure")
241 241 > # zzz prefix to ensure it sorted after store.write
242 242 > tr.addfinalize('zzz-forcefails', fail)
243 243 > return tr
244 244 >
245 245 > def uisetup(ui):
246 246 > wrapfunction(localrepo.localrepository, 'transaction', wrapper)
247 247 >
248 248 > cmdtable = {}
249 249 >
250 250 > EOF
251 251 $ rm -f "${extpath}c"
252 252 $ touch z
253 253 $ hg ci -qAm z
254 254 transaction abort!
255 255 rollback completed
256 256 abort: forced transaction failure
257 257 [255]
258 258 $ cat .hg/store/fncache
259 259 data/y.i
260 260
261 261 Aborted transactions can be recovered later
262 262
263 263 $ cat > ../exceptionext.py <<EOF
264 264 > import os
265 265 > from mercurial import commands, util, transaction, localrepo
266 266 > from mercurial.extensions import wrapfunction
267 267 >
268 268 > def trwrapper(orig, self, *args, **kwargs):
269 269 > tr = orig(self, *args, **kwargs)
270 270 > def fail(tr):
271 271 > raise util.Abort("forced transaction failure")
272 272 > # zzz prefix to ensure it sorted after store.write
273 273 > tr.addfinalize('zzz-forcefails', fail)
274 274 > return tr
275 275 >
276 276 > def abortwrapper(orig, self, *args, **kwargs):
277 277 > raise util.Abort("forced transaction failure")
278 278 >
279 279 > def uisetup(ui):
280 280 > wrapfunction(localrepo.localrepository, 'transaction', trwrapper)
281 281 > wrapfunction(transaction.transaction, '_abort', abortwrapper)
282 282 >
283 283 > cmdtable = {}
284 284 >
285 285 > EOF
286 286 $ rm -f "${extpath}c"
287 287 $ hg up -q 1
288 288 $ touch z
289 289 $ hg ci -qAm z 2>/dev/null
290 290 [255]
291 291 $ cat .hg/store/fncache | sort
292 292 data/y.i
293 293 data/z.i
294 294 $ hg recover
295 295 rolling back interrupted transaction
296 296 checking changesets
297 297 checking manifests
298 298 crosschecking files in changesets and manifests
299 299 checking files
300 300 1 files, 1 changesets, 1 total revisions
301 301 $ cat .hg/store/fncache
302 302 data/y.i
303 303
304 304 $ cd ..
305 305
306 306 debugrebuildfncache does nothing unless repo has fncache requirement
307 307
308 308 $ hg --config format.usefncache=false init nofncache
309 309 $ cd nofncache
310 310 $ hg debugrebuildfncache
311 (not rebuilding fncache because repository does not support fncache
311 (not rebuilding fncache because repository does not support fncache)
312 312
313 313 $ cd ..
314 314
315 315 debugrebuildfncache works on empty repository
316 316
317 317 $ hg init empty
318 318 $ cd empty
319 319 $ hg debugrebuildfncache
320 320 fncache already up to date
321 321 $ cd ..
322 322
323 323 debugrebuildfncache on an up to date repository no-ops
324 324
325 325 $ hg init repo
326 326 $ cd repo
327 327 $ echo initial > foo
328 328 $ echo initial > .bar
329 329 $ hg commit -A -m initial
330 330 adding .bar
331 331 adding foo
332 332
333 333 $ cat .hg/store/fncache | sort
334 334 data/.bar.i
335 335 data/foo.i
336 336
337 337 $ hg debugrebuildfncache
338 338 fncache already up to date
339 339
340 340 debugrebuildfncache restores deleted fncache file
341 341
342 342 $ rm -f .hg/store/fncache
343 343 $ hg debugrebuildfncache
344 344 adding data/.bar.i
345 345 adding data/foo.i
346 346 2 items added, 0 removed from fncache
347 347
348 348 $ cat .hg/store/fncache | sort
349 349 data/.bar.i
350 350 data/foo.i
351 351
352 352 Rebuild after rebuild should no-op
353 353
354 354 $ hg debugrebuildfncache
355 355 fncache already up to date
356 356
357 357 A single missing file should get restored, an extra file should be removed
358 358
359 359 $ cat > .hg/store/fncache << EOF
360 360 > data/foo.i
361 361 > data/bad-entry.i
362 362 > EOF
363 363
364 364 $ hg debugrebuildfncache
365 365 removing data/bad-entry.i
366 366 adding data/.bar.i
367 367 1 items added, 1 removed from fncache
368 368
369 369 $ cat .hg/store/fncache | sort
370 370 data/.bar.i
371 371 data/foo.i
372 372
373 373 $ cd ..
374 374
375 375 Try a simple variation without dotencode to ensure fncache is ignorant of encoding
376 376
377 377 $ hg --config format.dotencode=false init nodotencode
378 378 $ cd nodotencode
379 379 $ echo initial > foo
380 380 $ echo initial > .bar
381 381 $ hg commit -A -m initial
382 382 adding .bar
383 383 adding foo
384 384
385 385 $ cat .hg/store/fncache | sort
386 386 data/.bar.i
387 387 data/foo.i
388 388
389 389 $ rm .hg/store/fncache
390 390 $ hg debugrebuildfncache
391 391 adding data/.bar.i
392 392 adding data/foo.i
393 393 2 items added, 0 removed from fncache
394 394
395 395 $ cat .hg/store/fncache | sort
396 396 data/.bar.i
397 397 data/foo.i
General Comments 0
You need to be logged in to leave comments. Login now