diff --git a/mercurial/dispatch.py b/mercurial/dispatch.py --- a/mercurial/dispatch.py +++ b/mercurial/dispatch.py @@ -349,19 +349,20 @@ def _dispatch(ui, args): lui = ui.copy() lui.readconfig(os.path.join(path, ".hg", "hgrc")) + # Configure extensions in phases: uisetup, extsetup, cmdtable, and + # reposetup. Programs like TortoiseHg will call _dispatch several + # times so we keep track of configured extensions in _loaded. extensions.loadall(lui) - for name, module in extensions.extensions(): - if name in _loaded: - continue + exts = [ext for ext in extensions.extensions() if ext[0] not in _loaded] - # setup extensions - # TODO this should be generalized to scheme, where extensions can - # redepend on other extensions. then we should toposort them, and - # do initialization in correct order + # (uisetup is handled in extensions.loadall) + + for name, module in exts: extsetup = getattr(module, 'extsetup', None) if extsetup: extsetup() + for name, module in exts: cmdtable = getattr(module, 'cmdtable', {}) overrides = [cmd for cmd in cmdtable if cmd in commands.table] if overrides: @@ -370,6 +371,8 @@ def _dispatch(ui, args): commands.table.update(cmdtable) _loaded.add(name) + # (reposetup is handled in hg.repository) + addaliases(lui, commands.table) # check for fallback encoding diff --git a/mercurial/extensions.py b/mercurial/extensions.py --- a/mercurial/extensions.py +++ b/mercurial/extensions.py @@ -40,6 +40,7 @@ def loadpath(path, module_name): return imp.load_source(module_name, path) def load(ui, name, path): + # unused ui argument kept for backwards compatibility if name.startswith('hgext.') or name.startswith('hgext/'): shortname = name[6:] else: @@ -66,12 +67,9 @@ def load(ui, name, path): _extensions[shortname] = mod _order.append(shortname) - uisetup = getattr(mod, 'uisetup', None) - if uisetup: - uisetup(ui) - def loadall(ui): result = ui.configitems("extensions") + newindex = len(_order) for (name, path) in result: if path: if path[0] == '!': @@ -90,6 +88,11 @@ def loadall(ui): if ui.traceback(): return 1 + for name in _order[newindex:]: + uisetup = getattr(_extensions[name], 'uisetup', None) + if uisetup: + uisetup(ui) + def wrapcommand(table, command, wrapper): aliases, entry = cmdutil.findcmd(command, table) for alias, e in table.iteritems(): diff --git a/tests/test-extension b/tests/test-extension --- a/tests/test-extension +++ b/tests/test-extension @@ -55,6 +55,29 @@ cd a hg foo echo 'barfoo = !' >> $HGRCPATH +# check that extensions are loaded in phases +cat > foo.py <> $HGRCPATH +echo 'bar = bar.py' >> $HGRCPATH + +# command with no output, we just want to see the extensions loaded +hg paths + +echo 'foo = !' >> $HGRCPATH +echo 'bar = !' >> $HGRCPATH + cd .. cat > empty.py <