298 |
298 |
299 # a list of (ui, featureset) functions. |
299 # a list of (ui, featureset) functions. |
300 # only functions defined in module of enabled extensions are invoked |
300 # only functions defined in module of enabled extensions are invoked |
301 featuresetupfuncs = set() |
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 def __init__(self, baseui, path, create=False): |
323 def __init__(self, baseui, path, create=False): |
304 self.requirements = set() |
324 self.requirements = set() |
305 self.filtername = None |
325 self.filtername = None |
306 # wvfs: rooted at the repository root, used to access the working copy |
326 # wvfs: rooted at the repository root, used to access the working copy |
307 self.wvfs = vfsmod.vfs(path, expandpath=True, realpath=True) |
327 self.wvfs = vfsmod.vfs(path, expandpath=True, realpath=True) |
317 # These auditor are not used by the vfs, |
337 # These auditor are not used by the vfs, |
318 # only used when writing this comment: basectx.match |
338 # only used when writing this comment: basectx.match |
319 self.auditor = pathutil.pathauditor(self.root, self._checknested) |
339 self.auditor = pathutil.pathauditor(self.root, self._checknested) |
320 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested, |
340 self.nofsauditor = pathutil.pathauditor(self.root, self._checknested, |
321 realfs=False) |
341 realfs=False) |
322 self.vfs = vfsmod.vfs(self.path) |
|
323 self.baseui = baseui |
342 self.baseui = baseui |
324 self.ui = baseui.copy() |
343 self.ui = baseui.copy() |
325 self.ui.copy = baseui.copy # prevent copying repo configuration |
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 # A list of callback to shape the phase if no data were found. |
349 # A list of callback to shape the phase if no data were found. |
327 # Callback are in the form: func(repo, roots) --> processed root. |
350 # Callback are in the form: func(repo, roots) --> processed root. |
328 # This list it to be filled by extension during repo setup |
351 # This list it to be filled by extension during repo setup |
329 self._phasedefaults = [] |
352 self._phasedefaults = [] |
330 try: |
353 try: |
438 |
461 |
439 # Key to signature value. |
462 # Key to signature value. |
440 self._sparsesignaturecache = {} |
463 self._sparsesignaturecache = {} |
441 # Signature to cached matcher instance. |
464 # Signature to cached matcher instance. |
442 self._sparsematchercache = {} |
465 self._sparsematchercache = {} |
|
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 |
443 |
498 |
444 def close(self): |
499 def close(self): |
445 self._writecaches() |
500 self._writecaches() |
446 |
501 |
447 def _loadextensions(self): |
502 def _loadextensions(self): |