view hgext/largefiles/storefactory.py @ 31515:527a247f114f

merge: remove unnecessary matcher checks As part of changing manifest.diff to accept a matcher, a previous patch added matcher calls to each location in merge.manifestmerge that tested if 'x in mf' to maintain the same behavior as before. After analyzing it further, this matcher call isn't needed, and in fact hurts future patches ability to use the matcher here. Basically, all these 'if x in mf' checks were checking if a matched file's copy source was in the matcher as well. This meant if you passed a matcher for just file foo, it would not return file bar even if foo was a copy of bar. Since manifestmerge cares about copy information, let's allow all lookups of copy sources. We also update one spot with a 'is not None' check, since it wasn't obvious that the value could sometimes be None before, which broke when we called matcher(None). A future patch adds matcher optimizations to manifestmerge which causes this code path to get covered by existing tests.
author Durham Goode <durham@fb.com>
date Sun, 19 Mar 2017 11:42:17 -0700
parents 85868ecf2c0d
children cf841f2b5a72
line wrap: on
line source

# 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 re

from mercurial.i18n import _

from mercurial import (
    error,
    hg,
    util,
)

from . import (
    lfutil,
    localstore,
    wirestore,
)

# During clone this function is passed the src's ui object
# but it needs the dest's ui object so it can read out of
# the config file. Use repo.ui instead.
def openstore(repo, remote=None, put=False):
    ui = repo.ui

    if not remote:
        lfpullsource = getattr(repo, 'lfpullsource', None)
        if lfpullsource:
            path = ui.expandpath(lfpullsource)
        elif put:
            path = ui.expandpath('default-push', 'default')
        else:
            path = ui.expandpath('default')

        # ui.expandpath() leaves 'default-push' and 'default' alone if
        # they cannot be expanded: fallback to the empty string,
        # meaning the current directory.
        if path == 'default-push' or path == 'default':
            path = ''
            remote = repo
        else:
            path, _branches = hg.parseurl(path)
            remote = hg.peer(repo, {}, path)

    # The path could be a scheme so use Mercurial's normal functionality
    # to resolve the scheme to a repository and use its path
    path = util.safehasattr(remote, 'url') and remote.url() or remote.path

    match = _scheme_re.match(path)
    if not match:                       # regular filesystem path
        scheme = 'file'
    else:
        scheme = match.group(1)

    try:
        storeproviders = _storeprovider[scheme]
    except KeyError:
        raise error.Abort(_('unsupported URL scheme %r') % scheme)

    for classobj in storeproviders:
        try:
            return classobj(ui, repo, remote)
        except lfutil.storeprotonotcapable:
            pass

    raise error.Abort(_('%s does not appear to be a largefile store') %
                     util.hidepassword(path))

_storeprovider = {
    'file':  [localstore.localstore],
    'http':  [wirestore.wirestore],
    'https': [wirestore.wirestore],
    'ssh': [wirestore.wirestore],
    }

_scheme_re = re.compile(r'^([a-zA-Z0-9+-.]+)://')