# client.py -- Implementation of the server side git protocols
-# Copyright (C) 2008-2009 Jelmer Vernooij <jelmer@samba.org>
+# Copyright (C) 2008-2013 Jelmer Vernooij <jelmer@samba.org>
# Copyright (C) 2008 John Carr
#
# This program is free software; you can redistribute it and/or
from dulwich.pack import (
write_pack_objects,
)
+from dulwich.refs import (
+ read_info_refs,
+ )
# Python 2.6.6 included these in urlparse.uses_netloc upstream. Do
return refs, set(server_capabilities)
-def read_info_refs(f):
- ret = {}
- for l in f.readlines():
- (sha, name) = l.rstrip("\r\n").split("\t", 1)
- ret[name] = sha
- return ret
-
-
# TODO(durin42): this doesn't correctly degrade if the server doesn't
# support some capabilities. This should work properly with servers
# that don't support multi_ack.
report_activity=self._report_activity), p.can_read
+# What Git client to use for local access
+default_local_git_client_cls = SubprocessGitClient
+
class SSHVendor(object):
"""A client side SSH implementation."""
return refs
-def get_transport_and_path(uri, **kwargs):
- """Obtain a git client from a URI or path.
+def get_transport_and_path_from_url(url, **kwargs):
+ """Obtain a git client from a URL.
- :param uri: URI or path
+ :param url: URL to open
:param thin_packs: Whether or not thin packs should be retrieved
:param report_activity: Optional callback for reporting transport
activity.
:return: Tuple with client instance and relative path.
"""
- parsed = urlparse.urlparse(uri)
+ parsed = urlparse.urlparse(url)
if parsed.scheme == 'git':
return (TCPGitClient(parsed.hostname, port=parsed.port, **kwargs),
parsed.path)
username=parsed.username, **kwargs), path
elif parsed.scheme in ('http', 'https'):
return HttpGitClient(urlparse.urlunparse(parsed), **kwargs), parsed.path
+ elif parsed.scheme == 'file':
+ return default_local_git_client_cls(**kwargs), parsed.path
+
+ raise ValueError("unknown scheme '%s'" % parsed.scheme)
+
+
+def get_transport_and_path(location, **kwargs):
+ """Obtain a git client from a URL.
+
+ :param location: URL or path
+ :param thin_packs: Whether or not thin packs should be retrieved
+ :param report_activity: Optional callback for reporting transport
+ activity.
+ :return: Tuple with client instance and relative path.
+ """
+ # First, try to parse it as a URL
+ try:
+ return get_transport_and_path_from_url(location, **kwargs)
+ except ValueError:
+ pass
- if parsed.scheme and not parsed.netloc:
+ if ':' in location and not '@' in location:
# SSH with no user@, zero or one leading slash.
- return SSHGitClient(parsed.scheme, **kwargs), parsed.path
- elif parsed.scheme:
- raise ValueError('Unknown git protocol scheme: %s' % parsed.scheme)
- elif '@' in parsed.path and ':' in parsed.path:
+ (hostname, path) = location.split(':')
+ return SSHGitClient(hostname, **kwargs), path
+ elif '@' in location and ':' in location:
# SSH with user@host:foo.
- user_host, path = parsed.path.split(':')
+ user_host, path = location.split(':')
user, host = user_host.rsplit('@')
return SSHGitClient(host, username=user, **kwargs), path
# Otherwise, assume it's a local path.
- return SubprocessGitClient(**kwargs), uri
+ return default_local_git_client_cls(**kwargs), location