##// END OF EJS Templates
revset: add new topographical sort...
revset: add new topographical sort Sort revisions in reverse revision order but grouped by topographical branches. Visualised as a graph, instead of: o 4 | | o 3 | | | o 2 | | o | 1 |/ o 0 revisions on a 'main' branch are emitted before 'side' branches: o 4 | o 1 | | o 3 | | | o 2 |/ o 0 where what constitutes a 'main' branch is configurable, so the sort could also result in: o 3 | o 2 | | o 4 | | | o 1 |/ o 0 This sort was already available as an experimental option in the graphmod module, from which it is now removed. This sort is best used with hg log -G: $ hg log -G "sort(all(), topo)"

File last commit:

r29266:b3a677c8 default
r29348:2188f170 default
Show More
__init__.py
129 lines | 4.7 KiB | text/x-python | PythonLexer
# __init__.py - Startup and module loading logic for Mercurial.
#
# Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import imp
import os
import sys
import zipimport
from . import (
policy
)
__all__ = []
modulepolicy = policy.policy
# Modules that have both Python and C implementations. See also the
# set of .py files under mercurial/pure/.
_dualmodules = set([
'mercurial.base85',
'mercurial.bdiff',
'mercurial.diffhelpers',
'mercurial.mpatch',
'mercurial.osutil',
'mercurial.parsers',
])
class hgimporter(object):
"""Object that conforms to import hook interface defined in PEP-302."""
def find_module(self, name, path=None):
# We only care about modules that have both C and pure implementations.
if name in _dualmodules:
return self
return None
def load_module(self, name):
mod = sys.modules.get(name, None)
if mod:
return mod
mercurial = sys.modules['mercurial']
# The zip importer behaves sufficiently differently from the default
# importer to warrant its own code path.
loader = getattr(mercurial, '__loader__', None)
if isinstance(loader, zipimport.zipimporter):
def ziploader(*paths):
"""Obtain a zipimporter for a directory under the main zip."""
path = os.path.join(loader.archive, *paths)
zl = sys.path_importer_cache.get(path)
if not zl:
zl = zipimport.zipimporter(path)
return zl
try:
if modulepolicy == 'py':
raise ImportError()
zl = ziploader('mercurial')
mod = zl.load_module(name)
# Unlike imp, ziploader doesn't expose module metadata that
# indicates the type of module. So just assume what we found
# is OK (even though it could be a pure Python module).
except ImportError:
if modulepolicy == 'c':
raise
zl = ziploader('mercurial', 'pure')
mod = zl.load_module(name)
sys.modules[name] = mod
return mod
# Unlike the default importer which searches special locations and
# sys.path, we only look in the directory where "mercurial" was
# imported from.
# imp.find_module doesn't support submodules (modules with ".").
# Instead you have to pass the parent package's __path__ attribute
# as the path argument.
stem = name.split('.')[-1]
try:
if modulepolicy == 'py':
raise ImportError()
modinfo = imp.find_module(stem, mercurial.__path__)
# The Mercurial installer used to copy files from
# mercurial/pure/*.py to mercurial/*.py. Therefore, it's possible
# for some installations to have .py files under mercurial/*.
# Loading Python modules when we expected C versions could result
# in a) poor performance b) loading a version from a previous
# Mercurial version, potentially leading to incompatibility. Either
# scenario is bad. So we verify that modules loaded from
# mercurial/* are C extensions. If the current policy allows the
# loading of .py modules, the module will be re-imported from
# mercurial/pure/* below.
if modinfo[2][2] != imp.C_EXTENSION:
raise ImportError('.py version of %s found where C '
'version should exist' % name)
except ImportError:
if modulepolicy == 'c':
raise
# Could not load the C extension and pure Python is allowed. So
# try to load them.
from . import pure
modinfo = imp.find_module(stem, pure.__path__)
if not modinfo:
raise ImportError('could not find mercurial module %s' %
name)
mod = imp.load_module(name, *modinfo)
sys.modules[name] = mod
return mod
# We automagically register our custom importer as a side-effect of loading.
# This is necessary to ensure that any entry points are able to import
# mercurial.* modules without having to perform this registration themselves.
if not any(isinstance(x, hgimporter) for x in sys.meta_path):
# meta_path is used before any implicit finders and before sys.path.
sys.meta_path.insert(0, hgimporter())