Show More
@@ -234,6 +234,7 b' def reposetup(ui, repo):' | |||
|
234 | 234 | |
|
235 | 235 | if util.safehasattr(ui, 'setrepo'): |
|
236 | 236 | ui.setrepo(repo) |
|
237 | repo._wlockfreeprefix.add('blackbox.log') | |
|
237 | 238 | |
|
238 | 239 | @command('^blackbox', |
|
239 | 240 | [('l', 'limit', 10, _('the number of events to show')), |
@@ -69,6 +69,7 b' def extsetup(ui):' | |||
|
69 | 69 | def reposetup(ui, repo): |
|
70 | 70 | if repo.local(): |
|
71 | 71 | repo.journal = journalstorage(repo) |
|
72 | repo._wlockfreeprefix.add('namejournal') | |
|
72 | 73 | |
|
73 | 74 | dirstate, cached = localrepo.isfilecached(repo, 'dirstate') |
|
74 | 75 | if cached: |
@@ -122,6 +122,10 b' def uisetup(ui):' | |||
|
122 | 122 | cmdutil.extraexport.append('pullurl') |
|
123 | 123 | cmdutil.extraexportmap['pullurl'] = _addpullheader |
|
124 | 124 | |
|
125 | def reposetup(ui, repo): | |
|
126 | if not repo.local(): | |
|
127 | return | |
|
128 | repo._wlockfreeprefix.add('last-email.txt') | |
|
125 | 129 | |
|
126 | 130 | def prompt(ui, prompt, default=None, rest=':'): |
|
127 | 131 | if default: |
@@ -300,6 +300,26 b' class localrepository(object):' | |||
|
300 | 300 | # only functions defined in module of enabled extensions are invoked |
|
301 | 301 | featuresetupfuncs = set() |
|
302 | 302 | |
|
303 | # list of prefix for file which can be written without 'wlock' | |
|
304 | # Extensions should extend this list when needed | |
|
305 | _wlockfreeprefix = { | |
|
306 | # We migh consider requiring 'wlock' for the next | |
|
307 | # two, but pretty much all the existing code assume | |
|
308 | # wlock is not needed so we keep them excluded for | |
|
309 | # now. | |
|
310 | 'hgrc', | |
|
311 | 'requires', | |
|
312 | # XXX cache is a complicatged business someone | |
|
313 | # should investigate this in depth at some point | |
|
314 | 'cache/', | |
|
315 | # XXX shouldn't be dirstate covered by the wlock? | |
|
316 | 'dirstate', | |
|
317 | # XXX bisect was still a bit too messy at the time | |
|
318 | # this changeset was introduced. Someone should fix | |
|
319 | # the remainig bit and drop this line | |
|
320 | 'bisect.state', | |
|
321 | } | |
|
322 | ||
|
303 | 323 | def __init__(self, baseui, path, create=False): |
|
304 | 324 | self.requirements = set() |
|
305 | 325 | self.filtername = None |
@@ -319,10 +339,13 b' class localrepository(object):' | |||
|
319 | 339 | self.auditor = pathutil.pathauditor(self.root, self._checknested) |
|
320 | 340 | self.nofsauditor = pathutil.pathauditor(self.root, self._checknested, |
|
321 | 341 | realfs=False) |
|
322 | self.vfs = vfsmod.vfs(self.path) | |
|
323 | 342 | self.baseui = baseui |
|
324 | 343 | self.ui = baseui.copy() |
|
325 | 344 | self.ui.copy = baseui.copy # prevent copying repo configuration |
|
345 | self.vfs = vfsmod.vfs(self.path) | |
|
346 | if (self.ui.configbool('devel', 'all-warnings') or | |
|
347 | self.ui.configbool('devel', 'check-locks')): | |
|
348 | self.vfs.audit = self._getvfsward(self.vfs.audit) | |
|
326 | 349 | # A list of callback to shape the phase if no data were found. |
|
327 | 350 | # Callback are in the form: func(repo, roots) --> processed root. |
|
328 | 351 | # This list it to be filled by extension during repo setup |
@@ -441,6 +464,38 b' class localrepository(object):' | |||
|
441 | 464 | # Signature to cached matcher instance. |
|
442 | 465 | self._sparsematchercache = {} |
|
443 | 466 | |
|
467 | def _getvfsward(self, origfunc): | |
|
468 | """build a ward for self.vfs""" | |
|
469 | rref = weakref.ref(self) | |
|
470 | def checkvfs(path, mode=None): | |
|
471 | ret = origfunc(path, mode=mode) | |
|
472 | repo = rref() | |
|
473 | if (repo is None | |
|
474 | or not util.safehasattr(repo, '_wlockref') | |
|
475 | or not util.safehasattr(repo, '_lockref')): | |
|
476 | return | |
|
477 | if mode in (None, 'r', 'rb'): | |
|
478 | return | |
|
479 | if path.startswith(repo.path): | |
|
480 | # truncate name relative to the repository (.hg) | |
|
481 | path = path[len(repo.path) + 1:] | |
|
482 | if path.startswith('journal.'): | |
|
483 | # journal is covered by 'lock' | |
|
484 | if repo._currentlock(repo._lockref) is None: | |
|
485 | repo.ui.develwarn('write with no lock: "%s"' % path, | |
|
486 | stacklevel=2) | |
|
487 | elif repo._currentlock(repo._wlockref) is None: | |
|
488 | # rest of vfs files are covered by 'wlock' | |
|
489 | # | |
|
490 | # exclude special files | |
|
491 | for prefix in self._wlockfreeprefix: | |
|
492 | if path.startswith(prefix): | |
|
493 | return | |
|
494 | repo.ui.develwarn('write with no wlock: "%s"' % path, | |
|
495 | stacklevel=2) | |
|
496 | return ret | |
|
497 | return checkvfs | |
|
498 | ||
|
444 | 499 | def close(self): |
|
445 | 500 | self._writecaches() |
|
446 | 501 |
@@ -44,6 +44,11 b'' | |||
|
44 | 44 | > wl.release() |
|
45 | 45 | > lo.release() |
|
46 | 46 | > |
|
47 | > @command(b'no-wlock-write', [], '') | |
|
48 | > def nowlockwrite(ui, repo): | |
|
49 | > with repo.vfs(b'branch', 'a'): | |
|
50 | > pass | |
|
51 | > | |
|
47 | 52 | > @command(b'stripintr', [], '') |
|
48 | 53 | > def stripintr(ui, repo): |
|
49 | 54 | > lo = repo.lock() |
@@ -104,6 +109,11 b'' | |||
|
104 | 109 | $ hg properlocking |
|
105 | 110 | $ hg nowaitlocking |
|
106 | 111 | |
|
112 | Writing without lock | |
|
113 | ||
|
114 | $ hg no-wlock-write | |
|
115 | devel-warn: write with no wlock: "branch" at: $TESTTMP/buggylocking.py:* (nowlockwrite) (glob) | |
|
116 | ||
|
107 | 117 | Stripping from a transaction |
|
108 | 118 | |
|
109 | 119 | $ echo a > a |
General Comments 0
You need to be logged in to leave comments.
Login now