view hgext/narrow/__init__.py @ 36079:a2a6e724d61a

narrow: import experimental extension from narrowhg revision cb51d673e9c5 Adjustments: * renamed src to hgext/narrow * marked extension experimental * added correct copyright header where it was missing * updated hgrc extension enable line in library.sh * renamed library.sh to narrow-library.sh * dropped all files from repo root as they're not interesting * dropped test-pyflakes.t, test-check-code.t and test-check-py3-compat.t * renamed remaining tests to all be test-narrow-* when they didn't already * fixed test-narrow-expanddirstate.t to refer to narrow and not narrowhg * fixed tests that wanted `update -C .` instead of `merge --abort` * corrected a two-space indent in narrowspec.py * added a missing _() in narrowcommands.py * fixed imports to pass the import checker * narrow only adds its --include and --exclude to clone if sparse isn't enabled to avoid breaking test-duplicateoptions.py. This is a kludge, and we'll need to come up with a better solution in the future. These were more or less the minimum to import something that would pass tests and not create a bunch of files we'll never use. Changes I intend to make as followups: * rework the test-narrow-*-tree.t tests to use the new testcases functionality in run-tests.py * remove lots of monkeypatches of core things Differential Revision: https://phab.mercurial-scm.org/D1974
author Augie Fackler <augie@google.com>
date Mon, 29 Jan 2018 16:19:33 -0500
parents
children 9dc28d8ea61e
line wrap: on
line source

# __init__.py - narrowhg extension
#
# Copyright 2017 Google, Inc.
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
'''create clones which fetch history data for subset of files (EXPERIMENTAL)'''

from __future__ import absolute_import

from mercurial import __version__
if __version__.version < '3.7':
    raise ImportError(
        'narrowhg requires mercurial 3.7 or newer')

try:
    from .__versionnum__ import version
    __version__ = version
except ImportError:
    pass

from mercurial import (
    extensions,
    hg,
    localrepo,
    registrar,
    util,
    verify as verifymod,
)

from . import (
    narrowbundle2,
    narrowchangegroup,
    narrowcommands,
    narrowcopies,
    narrowdirstate,
    narrowmerge,
    narrowpatch,
    narrowrepo,
    narrowrevlog,
    narrowtemplates,
    narrowwirepeer,
)

configtable = {}
configitem = registrar.configitem(configtable)
# Narrowhg *has* support for serving ellipsis nodes (which are used at
# least by Google's internal server), but that support is pretty
# fragile and has a lot of problems on real-world repositories that
# have complex graph topologies. This could probably be corrected, but
# absent someone needing the full support for ellipsis nodes in
# repositories with merges, it's unlikely this work will get done. As
# of this writining in late 2017, all repositories large enough for
# ellipsis nodes to be a hard requirement also enforce strictly linear
# history for other scaling reasons.
configitem('experimental', 'narrowservebrokenellipses',
           default=False,
           alias=[('narrow', 'serveellipses')],
)

# Export the commands table for Mercurial to see.
cmdtable = narrowcommands.table

localrepo.localrepository._basesupported.add(narrowrepo.requirement)

def uisetup(ui):
    """Wraps user-facing mercurial commands with narrow-aware versions."""
    narrowrevlog.setup()
    narrowbundle2.setup()
    narrowmerge.setup()
    narrowtemplates.setup()
    narrowcommands.setup()
    narrowchangegroup.setup()
    narrowwirepeer.uisetup()

def reposetup(ui, repo):
    """Wraps local repositories with narrow repo support."""
    if not isinstance(repo, localrepo.localrepository):
        return

    if narrowrepo.requirement in repo.requirements:
        narrowrepo.wraprepo(repo, True)
        narrowcopies.setup(repo)
        narrowdirstate.setup(repo)
        narrowpatch.setup(repo)
        narrowwirepeer.reposetup(repo)

def _narrowvalidpath(orig, repo, path):
    matcher = getattr(repo, 'narrowmatch', None)
    if matcher is None:
        return orig(repo, path)
    matcher = matcher()
    if matcher.visitdir(path) or matcher(path):
        return orig(repo, path)
    return False

def _verifierinit(orig, self, repo, matcher=None):
    # The verifier's matcher argument was desgined for narrowhg, so it should
    # be None from core. If another extension passes a matcher (unlikely),
    # we'll have to fail until matchers can be composed more easily.
    assert matcher is None
    matcher = getattr(repo, 'narrowmatch', lambda: None)()
    orig(self, repo, matcher)

def extsetup(ui):
    if util.safehasattr(verifymod, '_validpath'):
        extensions.wrapfunction(verifymod, '_validpath', _narrowvalidpath)
    else:
        extensions.wrapfunction(verifymod.verifier, '__init__', _verifierinit)
    extensions.wrapfunction(hg, 'postshare', narrowrepo.wrappostshare)
    extensions.wrapfunction(hg, 'copystore', narrowrepo.unsharenarrowspec)