##// END OF EJS Templates
dirstate: ignore symlinks when fs cannot handle them (issue1888)...
dirstate: ignore symlinks when fs cannot handle them (issue1888) When the filesystem cannot handle the executable bit, we currently ignore it completely when looking for modified files. Similarly, it is impossible to set or clear the bit when the filesystem ignores it. This patch makes Mercurial treat symbolic links the same way. Symlinks are a little different since they manifest themselves as small files containing a filename (the symlink target). On Windows, these files show up as regular files, and on Linux and Mac they show up as real symlinks. Issue1888 presents a case where the symlink files are better ignored from the Windows side. A Linux client creates symlinks in a working copy which is shared over a network between Linux and Windows clients. The Samba server is helpful and defererences the symlink when the Windows client looks at it. This means that Mercurial on the Windows side sees file content instead of a file name in the symlink, and hence flags the link as modified. Ignoring the change would be much more helpful, similarly to how Mercurial does not report any changes when executable bits are ignored in a checkout on Windows. An initial checkout of a symbolic link on a file system that cannot handle symbolic links will still result in a regular file containing the target file name as its content. Sharing such a checkout with a Linux client will not turn the file into a symlink automatically, but 'hg revert' can fix that. After the revert, the Windows client will see the correct file content (provided by the Samba server when it follows the link on the Linux side) and otherwise ignore the change. Running 'hg perfstatus' 10 times gives these results: Before: After: min: 0.544703 min: 0.546549 med: 0.547592 med: 0.548881 avg: 0.549146 avg: 0.548549 max: 0.564112 max: 0.551504 The median time is increased about 0.24%.

File last commit:

r11469:c37f35d7 stable
r11769:ca6cebd8 stable
Show More
hook.py
150 lines | 5.3 KiB | text/x-python | PythonLexer
Matt Mackall
hooks: separate hook code into a separate module
r4622 # hook.py - hook support for mercurial
#
# Copyright 2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Matt Mackall
hooks: separate hook code into a separate module
r4622
from i18n import _
Simon Heimberg
separate import lines from mercurial and general python modules
r8312 import os, sys
import extensions, util
Matt Mackall
hooks: separate hook code into a separate module
r4622
def _pythonhook(ui, repo, name, hname, funcname, args, throw):
'''call python hook. hook is callable object, looked up as
name in python module. if callable returns "true", hook
fails, else passes. if hook raises exception, treated as
hook failure. exception propagates if throw is "true".
reason for "true" meaning "hook failed" is so that
unmodified commands (e.g. mercurial.commands.update) can
be run as hooks without wrappers to convert return values.'''
ui.note(_("calling hook %s: %s\n") % (hname, funcname))
obj = funcname
Dirkjan Ochtman
some modernization cleanups, forward compatibility
r8366 if not hasattr(obj, '__call__'):
Matt Mackall
hooks: separate hook code into a separate module
r4622 d = funcname.rfind('.')
if d == -1:
raise util.Abort(_('%s hook is invalid ("%s" not in '
'a module)') % (hname, funcname))
modname = funcname[:d]
Sune Foldager
hook: fix bug (reuse of variable) introduced in 872d49dd577a...
r10103 oldpaths = sys.path
Steve Borho
hook: fix full path imports on Windows (issue1779)...
r9332 if hasattr(sys, "frozen"):
# binary installs require sys.path manipulation
Sune Foldager
hook: fix bug (reuse of variable) introduced in 872d49dd577a...
r10103 modpath, modfile = os.path.split(modname)
if modpath and modfile:
sys.path = sys.path[:] + [modpath]
modname = modfile
Matt Mackall
hooks: separate hook code into a separate module
r4622 try:
obj = __import__(modname)
except ImportError:
Bryan O'Sullivan
Make it possible to debug failed hook imports via use of --traceback...
r9851 e1 = sys.exc_type, sys.exc_value, sys.exc_traceback
Matt Mackall
hooks: separate hook code into a separate module
r4622 try:
# extensions are loaded with hgext_ prefix
obj = __import__("hgext_%s" % modname)
except ImportError:
Bryan O'Sullivan
Make it possible to debug failed hook imports via use of --traceback...
r9851 e2 = sys.exc_type, sys.exc_value, sys.exc_traceback
if ui.tracebackflag:
ui.warn(_('exception from first failed import attempt:\n'))
ui.traceback(e1)
if ui.tracebackflag:
ui.warn(_('exception from second failed import attempt:\n'))
ui.traceback(e2)
Matt Mackall
hooks: separate hook code into a separate module
r4622 raise util.Abort(_('%s hook is invalid '
'(import of "%s" failed)') %
(hname, modname))
Steve Borho
hook: fix full path imports on Windows (issue1779)...
r9332 sys.path = oldpaths
Matt Mackall
hooks: separate hook code into a separate module
r4622 try:
for p in funcname.split('.')[1:]:
obj = getattr(obj, p)
Benoit Boissinot
remove unused variables
r7280 except AttributeError:
Matt Mackall
hooks: separate hook code into a separate module
r4622 raise util.Abort(_('%s hook is invalid '
'("%s" is not defined)') %
(hname, funcname))
Dirkjan Ochtman
some modernization cleanups, forward compatibility
r8366 if not hasattr(obj, '__call__'):
Matt Mackall
hooks: separate hook code into a separate module
r4622 raise util.Abort(_('%s hook is invalid '
'("%s" is not callable)') %
(hname, funcname))
try:
r = obj(ui=ui, repo=repo, hooktype=name, **args)
Matt Mackall
error: move SignalInterrupt...
r7644 except KeyboardInterrupt:
Matt Mackall
hooks: separate hook code into a separate module
r4622 raise
except Exception, exc:
if isinstance(exc, util.Abort):
ui.warn(_('error: %s hook failed: %s\n') %
(hname, exc.args[0]))
else:
ui.warn(_('error: %s hook raised an exception: '
'%s\n') % (hname, exc))
if throw:
raise
Matt Mackall
ui: print_exc() -> traceback()
r8206 ui.traceback()
Matt Mackall
hooks: separate hook code into a separate module
r4622 return True
if r:
if throw:
raise util.Abort(_('%s hook failed') % hname)
ui.warn(_('warning: %s hook failed\n') % hname)
return r
def _exthook(ui, repo, name, cmd, args, throw):
ui.note(_("running hook %s: %s\n") % (name, cmd))
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787
env = {}
for k, v in args.iteritems():
Dirkjan Ochtman
some modernization cleanups, forward compatibility
r8366 if hasattr(v, '__call__'):
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 v = v()
env['HG_' + k.upper()] = v
Matt Mackall
hooks: fix pre- and post- hooks specified in .hg/hgrc...
r5869 if repo:
cwd = repo.root
else:
cwd = os.getcwd()
Maxim Khitrov
http: deliver hook output to client
r11469 if 'HG_URL' in env and env['HG_URL'].startswith('remote:http'):
r = util.system(cmd, environ=env, cwd=cwd, out=ui)
else:
r = util.system(cmd, environ=env, cwd=cwd)
Matt Mackall
hooks: separate hook code into a separate module
r4622 if r:
desc, r = util.explain_exit(r)
if throw:
raise util.Abort(_('%s hook %s') % (name, desc))
ui.warn(_('warning: %s hook %s\n') % (name, desc))
return r
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 _redirect = False
def redirect(state):
Alexis S. L. Carvalho
hook.py: fix redirections introduced by 323b9c55b328...
r6266 global _redirect
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 _redirect = state
Matt Mackall
hooks: separate hook code into a separate module
r4622 def hook(ui, repo, name, throw=False, **args):
r = False
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833
Sune Foldager
hook: only redirect stdout if it and stderr are valid files...
r9658 oldstdout = -1
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833 if _redirect:
Sune Foldager
hook: only redirect stdout if it and stderr are valid files...
r9658 stdoutno = sys.__stdout__.fileno()
stderrno = sys.__stderr__.fileno()
# temporarily redirect stdout to stderr, if possible
if stdoutno >= 0 and stderrno >= 0:
oldstdout = os.dup(stdoutno)
os.dup2(stderrno, stdoutno)
Matt Mackall
hook: redirect stdout to stderr for ssh and http servers
r5833
Jesse Long
hooks: restore io correctly on exception
r7416 try:
Matt Mackall
replace util.sort with sorted built-in...
r8209 for hname, cmd in ui.configitems('hooks'):
Jesse Long
hooks: restore io correctly on exception
r7416 if hname.split('.')[0] != name or not cmd:
continue
Dirkjan Ochtman
some modernization cleanups, forward compatibility
r8366 if hasattr(cmd, '__call__'):
Jesse Long
hooks: restore io correctly on exception
r7416 r = _pythonhook(ui, repo, name, hname, cmd, args, throw) or r
elif cmd.startswith('python:'):
Steve Borho
hook: fix full path imports on Windows (issue1779)...
r9332 if cmd.count(':') >= 2:
path, cmd = cmd[7:].rsplit(':', 1)
mod = extensions.loadpath(path, 'hghook.%s' % hname)
Alexander Solovyov
ability to load hooks from arbitrary python module
r7916 hookfn = getattr(mod, cmd)
else:
hookfn = cmd[7:].strip()
r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r
Jesse Long
hooks: restore io correctly on exception
r7416 else:
r = _exthook(ui, repo, hname, cmd, args, throw) or r
finally:
Sune Foldager
hook: only redirect stdout if it and stderr are valid files...
r9658 if _redirect and oldstdout >= 0:
os.dup2(oldstdout, stdoutno)
Jesse Long
hooks: restore io correctly on exception
r7416 os.close(oldstdout)
Alexis S. L. Carvalho
hook.py: fix redirections introduced by 323b9c55b328...
r6266
return r