##// END OF EJS Templates
histedit: proper phase conservation (issue3724)...
histedit: proper phase conservation (issue3724) Before this changeset, histedit created all new changesets according phases.new-commit option without any regards for the phases of the original changesets. This changeset fix that using the phase of rewritten changeset to decide the phase of the resulting changeset. In case of reordering or folding, we keep secret item secret as it seems the safer path. temporary commit creation are not affected. They are head only and stripped at the end of the histedit. As for the resolution of issue3681 (obsolescence cycle prevention), we do not handle changesets created by edit command.

File last commit:

r18111:d7c28954 default
r18440:35513c59 default
Show More
hook.py
193 lines | 7.2 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
Dirkjan Ochtman
hook: disable demandimport before importing hooks...
r18111 import extensions, util, demandimport
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
Augie Fackler
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
r14943 if not util.safehasattr(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
Augie Fackler
windows: check util.mainfrozen() instead of ad-hoc checks everywhere
r14941 if util.mainfrozen():
Steve Borho
hook: fix full path imports on Windows (issue1779)...
r9332 # 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:
Dirkjan Ochtman
hook: disable demandimport before importing hooks...
r18111 demandimport.disable()
Matt Mackall
hooks: separate hook code into a separate module
r4622 obj = __import__(modname)
Dirkjan Ochtman
hook: disable demandimport before importing hooks...
r18111 demandimport.enable()
Matt Mackall
hooks: separate hook code into a separate module
r4622 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)
Dirkjan Ochtman
hook: disable demandimport before importing hooks...
r18111 demandimport.enable()
Matt Mackall
hooks: separate hook code into a separate module
r4622 except ImportError:
Dirkjan Ochtman
hook: disable demandimport before importing hooks...
r18111 demandimport.enable()
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))
Augie Fackler
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
r14943 if not util.safehasattr(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:
Lee Cantey
hooks: use python 2.4 compatible exception handling
r14916 try:
Mads Kiilerich
help: fix some instances of 'the the'
r17251 # redirect IO descriptors to the ui descriptors so hooks
Lee Cantey
hooks: use python 2.4 compatible exception handling
r14916 # that write directly to these don't mess up the command
# protocol when running through the command server
old = sys.stdout, sys.stderr, sys.stdin
sys.stdout, sys.stderr, sys.stdin = ui.fout, ui.ferr, ui.fin
Idan Kamara
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks...
r14889
Lee Cantey
hooks: use python 2.4 compatible exception handling
r14916 r = obj(ui=ui, repo=repo, hooktype=name, **args)
except KeyboardInterrupt:
Matt Mackall
hooks: separate hook code into a separate module
r4622 raise
Lee Cantey
hooks: use python 2.4 compatible exception handling
r14916 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
ui.traceback()
return True
Idan Kamara
hooks: redirect stdout/err/in to the ui descriptors when calling python hooks...
r14889 finally:
sys.stdout, sys.stderr, sys.stdin = old
Matt Mackall
hooks: separate hook code into a separate module
r4622 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():
Augie Fackler
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
r14943 if util.safehasattr(v, '__call__'):
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 v = v()
Dan Villiom Podlaski Christiansen
hooks: sort any dictionaries set in the environment...
r13207 if isinstance(v, dict):
# make the dictionary element order stable across Python
# implementations
v = ('{' +
', '.join('%r: %r' % i for i in sorted(v.iteritems())) +
'}')
Matt Mackall
Introduce HG_PREPEND to solve pretxn races...
r7787 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:
Idan Kamara
hook: write hook output to ui fout descriptor...
r14711 r = util.system(cmd, environ=env, cwd=cwd, out=ui.fout)
Matt Mackall
hooks: separate hook code into a separate module
r4622 if r:
Adrian Buehlmann
rename explain_exit to explainexit
r14234 desc, r = util.explainexit(r)
Matt Mackall
hooks: separate hook code into a separate module
r4622 if throw:
raise util.Abort(_('%s hook %s') % (name, desc))
ui.warn(_('warning: %s hook %s\n') % (name, desc))
return r
Matt Zuba
hooks: prioritize run order of hooks...
r15896 def _allhooks(ui):
hooks = []
for name, cmd in ui.configitems('hooks'):
if not name.startswith('priority'):
priority = ui.configint('hooks', 'priority.%s' % name, 0)
hooks.append((-priority, len(hooks), name, cmd))
return [(k, v) for p, o, k, v in sorted(hooks)]
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):
Idan Kamara
ui: add a variable to control whether hooks should be called...
r17048 if not ui.callhooks:
return False
Matt Mackall
hooks: separate hook code into a separate module
r4622 r = False
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
Jesse Long
hooks: restore io correctly on exception
r7416 try:
Matt Zuba
hooks: prioritize run order of hooks...
r15896 for hname, cmd in _allhooks(ui):
Jesse Long
hooks: restore io correctly on exception
r7416 if hname.split('.')[0] != name or not cmd:
continue
Matt Mackall
hooks: delay I/O redirection until we actually run a hook (issue3711)...
r17963
if oldstdout == -1 and _redirect:
try:
stdoutno = sys.__stdout__.fileno()
stderrno = sys.__stderr__.fileno()
# temporarily redirect stdout to stderr, if possible
if stdoutno >= 0 and stderrno >= 0:
sys.__stdout__.flush()
oldstdout = os.dup(stdoutno)
os.dup2(stderrno, stdoutno)
Matt Mackall
hooks: be even more forgiven of non-fd descriptors (issue3711)...
r17964 except (OSError, AttributeError):
# files seem to be bogus, give up on redirecting (WSGI, etc)
Matt Mackall
hooks: delay I/O redirection until we actually run a hook (issue3711)...
r17963 pass
Augie Fackler
globally: use safehasattr(x, '__call__') instead of hasattr(x, '__call__')
r14943 if util.safehasattr(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)
Alexander Solovyov
hook: assume relative path to hook is given from repo root
r13118 path = util.expandpath(path)
Matt Mackall
hook: fix import path handling for repo=None
r13119 if repo:
path = os.path.join(repo.root, path)
Simon Heimberg
hooks: print out more information when loading a python hook fails...
r17217 try:
mod = extensions.loadpath(path, 'hghook.%s' % hname)
except Exception:
ui.write(_("loading %s hook failed:\n") % hname)
raise
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