Show More
@@ -823,13 +823,17 b' class localrepository(object):' | |||||
823 | raise error.RepoError( |
|
823 | raise error.RepoError( | |
824 | _("abandoned transaction found - run hg recover")) |
|
824 | _("abandoned transaction found - run hg recover")) | |
825 |
|
825 | |||
|
826 | def onclose(): | |||
|
827 | self.store.write(tr) | |||
|
828 | ||||
826 | self._writejournal(desc) |
|
829 | self._writejournal(desc) | |
827 | renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()] |
|
830 | renames = [(vfs, x, undoname(x)) for vfs, x in self._journalfiles()] | |
828 | rp = report and report or self.ui.warn |
|
831 | rp = report and report or self.ui.warn | |
829 | tr = transaction.transaction(rp, self.sopener, |
|
832 | tr = transaction.transaction(rp, self.sopener, | |
830 | "journal", |
|
833 | "journal", | |
831 | aftertrans(renames), |
|
834 | aftertrans(renames), | |
832 |
self.store.createmode |
|
835 | self.store.createmode, | |
|
836 | onclose) | |||
833 | self._transref = weakref.ref(tr) |
|
837 | self._transref = weakref.ref(tr) | |
834 | return tr |
|
838 | return tr | |
835 |
|
839 | |||
@@ -1037,7 +1041,6 b' class localrepository(object):' | |||||
1037 | return l |
|
1041 | return l | |
1038 |
|
1042 | |||
1039 | def unlock(): |
|
1043 | def unlock(): | |
1040 | self.store.write() |
|
|||
1041 | if hasunfilteredcache(self, '_phasecache'): |
|
1044 | if hasunfilteredcache(self, '_phasecache'): | |
1042 | self._phasecache.write() |
|
1045 | self._phasecache.write() | |
1043 | for k, ce in self._filecache.items(): |
|
1046 | for k, ce in self._filecache.items(): |
@@ -337,7 +337,7 b' class basicstore(object):' | |||||
337 | def copylist(self): |
|
337 | def copylist(self): | |
338 | return ['requires'] + _data.split() |
|
338 | return ['requires'] + _data.split() | |
339 |
|
339 | |||
340 | def write(self): |
|
340 | def write(self, tr): | |
341 | pass |
|
341 | pass | |
342 |
|
342 | |||
343 | def __contains__(self, path): |
|
343 | def __contains__(self, path): | |
@@ -402,8 +402,9 b' class fncache(object):' | |||||
402 | raise util.Abort(t) |
|
402 | raise util.Abort(t) | |
403 | fp.close() |
|
403 | fp.close() | |
404 |
|
404 | |||
405 | def write(self): |
|
405 | def write(self, tr): | |
406 | if self._dirty: |
|
406 | if self._dirty: | |
|
407 | tr.addbackup('fncache') | |||
407 | fp = self.vfs('fncache', mode='wb', atomictemp=True) |
|
408 | fp = self.vfs('fncache', mode='wb', atomictemp=True) | |
408 | if self.entries: |
|
409 | if self.entries: | |
409 | fp.write(encodedir('\n'.join(self.entries) + '\n')) |
|
410 | fp.write(encodedir('\n'.join(self.entries) + '\n')) | |
@@ -485,8 +486,8 b' class fncachestore(basicstore):' | |||||
485 | return (['requires', '00changelog.i'] + |
|
486 | return (['requires', '00changelog.i'] + | |
486 | ['store/' + f for f in d.split()]) |
|
487 | ['store/' + f for f in d.split()]) | |
487 |
|
488 | |||
488 | def write(self): |
|
489 | def write(self, tr): | |
489 | self.fncache.write() |
|
490 | self.fncache.write(tr) | |
490 |
|
491 | |||
491 | def _exists(self, f): |
|
492 | def _exists(self, f): | |
492 | ef = self.encode(f) |
|
493 | ef = self.encode(f) |
@@ -177,4 +177,62 b' Encoding of reserved / long paths in the' | |||||
177 |
|
177 | |||
178 | $ cd .. |
|
178 | $ cd .. | |
179 |
|
179 | |||
|
180 | Aborting lock does not prevent fncache writes | |||
180 |
|
181 | |||
|
182 | $ cat > exceptionext.py <<EOF | |||
|
183 | > import os | |||
|
184 | > from mercurial import commands, util | |||
|
185 | > from mercurial.extensions import wrapfunction | |||
|
186 | > | |||
|
187 | > def lockexception(orig, vfs, lockname, wait, releasefn, acquirefn, desc): | |||
|
188 | > def releasewrap(): | |||
|
189 | > raise util.Abort("forced lock failure") | |||
|
190 | > return orig(vfs, lockname, wait, releasewrap, acquirefn, desc) | |||
|
191 | > | |||
|
192 | > def reposetup(ui, repo): | |||
|
193 | > wrapfunction(repo, '_lock', lockexception) | |||
|
194 | > | |||
|
195 | > cmdtable = {} | |||
|
196 | > | |||
|
197 | > EOF | |||
|
198 | $ extpath=`pwd`/exceptionext.py | |||
|
199 | $ hg init fncachetxn | |||
|
200 | $ cd fncachetxn | |||
|
201 | $ printf "[extensions]\nexceptionext=$extpath\n" >> .hg/hgrc | |||
|
202 | $ touch y | |||
|
203 | $ hg ci -qAm y | |||
|
204 | abort: forced lock failure | |||
|
205 | [255] | |||
|
206 | $ cat .hg/store/fncache | |||
|
207 | data/y.i | |||
|
208 | ||||
|
209 | Aborting transaction prevents fncache change | |||
|
210 | ||||
|
211 | $ cat > ../exceptionext.py <<EOF | |||
|
212 | > import os | |||
|
213 | > from mercurial import commands, util, transaction | |||
|
214 | > from mercurial.extensions import wrapfunction | |||
|
215 | > | |||
|
216 | > def wrapper(orig, self, *args, **kwargs): | |||
|
217 | > origonclose = self.onclose | |||
|
218 | > def onclose(): | |||
|
219 | > origonclose() | |||
|
220 | > raise util.Abort("forced transaction failure") | |||
|
221 | > self.onclose = onclose | |||
|
222 | > return orig(self, *args, **kwargs) | |||
|
223 | > | |||
|
224 | > def uisetup(ui): | |||
|
225 | > wrapfunction(transaction.transaction, 'close', wrapper) | |||
|
226 | > | |||
|
227 | > cmdtable = {} | |||
|
228 | > | |||
|
229 | > EOF | |||
|
230 | $ rm "${extpath}c" | |||
|
231 | $ touch z | |||
|
232 | $ hg ci -qAm z | |||
|
233 | transaction abort! | |||
|
234 | rollback completed | |||
|
235 | abort: forced transaction failure | |||
|
236 | [255] | |||
|
237 | $ cat .hg/store/fncache | |||
|
238 | data/y.i |
General Comments 0
You need to be logged in to leave comments.
Login now