/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
0.358.2 by Jelmer Vernooij
Refresh copyright headers, add my email.
1
# Copyright (C) 2007-2018 Jelmer Vernooij <jelmer@jelmer.uk>
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
0.358.1 by Jelmer Vernooij
Fix FSF address.
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
16
0.358.3 by Jelmer Vernooij
Enable absolute import.
17
"""Remote dirs, repositories and branches."""
18
0.200.1594 by Jelmer Vernooij
Use absolute_import everywhere.
19
from __future__ import absolute_import
20
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
21
import gzip
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
22
import re
23
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
24
from .. import (
0.200.596 by Jelmer Vernooij
Import RemoteGitBranch._get_config().
25
    config,
0.200.707 by Jelmer Vernooij
Add debug routines.
26
    debug,
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
27
    errors,
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
28
    osutils,
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
29
    trace,
0.200.333 by Jelmer Vernooij
Support progress reporting when creating index.
30
    ui,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
31
    urlutils,
32
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
33
from ..push import (
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
34
    PushResult,
35
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
36
from ..errors import (
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
37
    AlreadyBranchError,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
38
    BzrError,
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
39
    DivergedBranches,
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
40
    InProcessTransport,
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
41
    InvalidRevisionId,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
42
    NoSuchFile,
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
43
    NoSuchRevision,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
44
    NoSuchTag,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
45
    NotBranchError,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
46
    NotLocalUrl,
7103.1.2 by Jelmer Vernooij
Handle PermissionDenied.
47
    PermissionDenied,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
48
    UninitializableFormat,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
49
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
50
from ..revisiontree import RevisionTree
7289.1.2 by Jelmer Vernooij
Fix pushing of tags as part of nascent git branches.
51
from ..sixish import (
52
    text_type,
53
    viewitems,
54
    )
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
55
from ..transport import (
0.200.292 by Jelmer Vernooij
Fix formatting.
56
    Transport,
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
57
    register_urlparse_netloc_protocol,
0.200.292 by Jelmer Vernooij
Fix formatting.
58
    )
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
59
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
60
from . import (
0.200.292 by Jelmer Vernooij
Fix formatting.
61
    lazy_check_versions,
7359.1.1 by Jelmer Vernooij
Only set user agent for GitHub.
62
    is_github_url,
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
63
    user_agent_for_github,
0.200.292 by Jelmer Vernooij
Fix formatting.
64
    )
0.200.200 by Jelmer Vernooij
Register lazily where possible.
65
lazy_check_versions()
66
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
67
from .branch import (
0.200.292 by Jelmer Vernooij
Fix formatting.
68
    GitBranch,
0.295.1 by Jelmer Vernooij
Split up branch formats.
69
    GitBranchFormat,
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
70
    GitBranchPushResult,
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
71
    GitTags,
0.406.2 by Jelmer Vernooij
Add tests.
72
    _quick_lookup_revno,
0.200.292 by Jelmer Vernooij
Fix formatting.
73
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
74
from .dir import (
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
75
    GitControlDirFormat,
76
    GitDir,
77
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
78
from .errors import (
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
79
    GitSmartRemoteNotSupported,
0.200.292 by Jelmer Vernooij
Fix formatting.
80
    NoSuchRef,
81
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
82
from .mapping import (
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
83
    mapping_registry,
84
    )
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
85
from .object_store import (
86
    get_object_store,
87
    )
0.404.5 by Jelmer Vernooij
Check for diverged branches during push.
88
from .push import (
89
    remote_divergence,
90
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
91
from .repository import (
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
92
    GitRepository,
7290.20.3 by Jelmer Vernooij
Fix tests for git/full history branches.
93
    GitRepositoryFormat,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
94
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
95
from .refs import (
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
96
    branch_name_to_ref,
0.200.1487 by Jelmer Vernooij
Use peeling.
97
    is_peeled,
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
98
    ref_to_tag_name,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
99
    tag_name_to_ref,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
100
    )
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
101
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
102
import dulwich
103
import dulwich.client
0.200.292 by Jelmer Vernooij
Fix formatting.
104
from dulwich.errors import (
105
    GitProtocolError,
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
106
    HangupException,
0.200.292 by Jelmer Vernooij
Fix formatting.
107
    )
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
108
from dulwich.pack import (
109
    Pack,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
110
    pack_objects_to_data,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
111
    )
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
112
from dulwich.protocol import ZERO_SHA
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
113
from dulwich.refs import (
114
    DictRefsContainer,
115
    SYMREF,
116
    )
117
from dulwich.repo import (
118
    NotGitRepository,
119
    )
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
120
import os
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
121
import select
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
122
import tempfile
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
123
124
try:
125
    import urllib.parse as urlparse
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
126
    from urllib.parse import splituser
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
127
except ImportError:
128
    import urlparse
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
129
    from urllib import splituser
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
130
131
# urlparse only supports a limited number of schemes by default
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
132
register_urlparse_netloc_protocol('git')
133
register_urlparse_netloc_protocol('git+ssh')
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
134
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
135
from dulwich.pack import load_pack_index
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
136
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
137
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
138
class GitPushResult(PushResult):
139
140
    def _lookup_revno(self, revid):
0.406.2 by Jelmer Vernooij
Add tests.
141
        try:
142
            return _quick_lookup_revno(self.source_branch, self.target_branch,
7143.15.2 by Jelmer Vernooij
Run autopep8.
143
                                       revid)
0.406.2 by Jelmer Vernooij
Add tests.
144
        except GitSmartRemoteNotSupported:
145
            return None
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
146
147
    @property
148
    def old_revno(self):
149
        return self._lookup_revno(self.old_revid)
150
151
    @property
152
    def new_revno(self):
153
        return self._lookup_revno(self.new_revid)
154
155
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
156
# Don't run any tests on GitSmartTransport as it is not intended to be
0.200.181 by Jelmer Vernooij
Support setting tags.
157
# a full implementation of Transport
158
def get_test_permutations():
159
    return []
160
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
161
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
162
def split_git_url(url):
0.200.709 by Jelmer Vernooij
When unpacking URLs, strip leftmost slash to match gits behaviour.
163
    """Split a Git URL.
164
165
    :param url: Git URL
166
    :return: Tuple with host, port, username, path.
167
    """
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
168
    parsed_url = urlparse.urlparse(url)
169
    path = urlparse.unquote(parsed_url.path)
0.246.2 by Jelmer Vernooij
Improve the fix dealing with git repo's in home directories.
170
    if path.startswith("/~"):
0.200.709 by Jelmer Vernooij
When unpacking URLs, strip leftmost slash to match gits behaviour.
171
        path = path[1:]
7290.38.1 by Jelmer Vernooij
Backport python3.8 support patch to breezy 3.0.
172
    return ((parsed_url.hostname or '', parsed_url.port, parsed_url.username, path))
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
173
174
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
175
class RemoteGitError(BzrError):
176
0.290.1 by Jelmer Vernooij
Avoid 'message' argument in RemoteGitError; apparently it breaks some versions of Python.
177
    _fmt = "Remote server error: %(msg)s"
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
178
179
7103.1.1 by Jelmer Vernooij
Improved error parsing for Git branches.
180
class HeadUpdateFailed(BzrError):
181
182
    _fmt = ("Unable to update remote HEAD branch. To update the master "
183
            "branch, specify the URL %(base_url)s,branch=master.")
184
185
    def __init__(self, base_url):
186
        super(HeadUpdateFailed, self).__init__()
187
        self.base_url = base_url
188
189
0.200.1275 by Jelmer Vernooij
recognize missing repositories
190
def parse_git_error(url, message):
191
    """Parse a remote git server error and return a bzr exception.
192
193
    :param url: URL of the remote repository
194
    :param message: Message sent by the remote git server
195
    """
196
    message = str(message).strip()
7143.15.2 by Jelmer Vernooij
Run autopep8.
197
    if (message.startswith("Could not find Repository ")
198
        or message == 'Repository not found.'
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
199
            or (message.startswith('Repository ') and
200
                message.endswith(' not found.'))):
0.200.1275 by Jelmer Vernooij
recognize missing repositories
201
        return NotBranchError(url, message)
0.200.1563 by Jelmer Vernooij
Improve error message.
202
    if message == "HEAD failed to update":
203
        base_url, _ = urlutils.split_segment_parameters(url)
7103.1.1 by Jelmer Vernooij
Improved error parsing for Git branches.
204
        return HeadUpdateFailed(base_url)
7103.1.2 by Jelmer Vernooij
Handle PermissionDenied.
205
    if message.startswith('access denied or repository not exported:'):
7103.1.3 by Jelmer Vernooij
Strip space.
206
        extra, path = message.split(': ', 1)
7103.1.2 by Jelmer Vernooij
Handle PermissionDenied.
207
        return PermissionDenied(path, extra)
7131.7.4 by Jelmer Vernooij
Don't use GitLab string.
208
    if message.endswith('You are not allowed to push code to this project.'):
7131.7.2 by Jelmer Vernooij
Handle github PermissionDenied.
209
        return PermissionDenied(url, message)
7131.7.3 by Jelmer Vernooij
Handle one more error.
210
    if message.endswith(' does not appear to be a git repository'):
211
        return NotBranchError(url, message)
7379.1.1 by Jelmer Vernooij
Handle invalid repository name on GitHub.
212
    if re.match('(.+) is not a valid repository name',
213
                message.splitlines()[0]):
214
        return NotBranchError(url, message)
7131.7.2 by Jelmer Vernooij
Handle github PermissionDenied.
215
    m = re.match(r'Permission to ([^ ]+) denied to ([^ ]+)\.', message)
216
    if m:
217
        return PermissionDenied(m.group(1), 'denied to %s' % m.group(2))
0.200.1275 by Jelmer Vernooij
recognize missing repositories
218
    # Don't know, just return it to the user as-is
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
219
    return RemoteGitError(message)
0.200.1275 by Jelmer Vernooij
recognize missing repositories
220
221
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
222
class GitSmartTransport(Transport):
223
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
224
    def __init__(self, url, _client=None):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
225
        Transport.__init__(self, url)
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
226
        (self._host, self._port, self._username, self._path) = \
227
            split_git_url(url)
0.200.707 by Jelmer Vernooij
Add debug routines.
228
        if 'transport' in debug.debug_flags:
229
            trace.mutter('host: %r, user: %r, port: %r, path: %r',
230
                         self._host, self._username, self._port, self._path)
0.200.166 by Jelmer Vernooij
don't reuse client objects.
231
        self._client = _client
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
232
        self._stripped_path = self._path.rsplit(",", 1)[0]
0.200.166 by Jelmer Vernooij
don't reuse client objects.
233
0.200.543 by Jelmer Vernooij
Implement GitSmartTransport.external_url().
234
    def external_url(self):
235
        return self.base
236
0.200.238 by Jelmer Vernooij
Import Transport.has().
237
    def has(self, relpath):
238
        return False
239
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
240
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
241
        raise NotImplementedError(self._get_client)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
242
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
243
    def _get_path(self):
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
244
        return self._stripped_path
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
245
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
246
    def get(self, path):
247
        raise NoSuchFile(path)
248
0.200.160 by Jelmer Vernooij
Implement abspath.
249
    def abspath(self, relpath):
250
        return urlutils.join(self.base, relpath)
251
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
252
    def clone(self, offset=None):
253
        """See Transport.clone()."""
254
        if offset is None:
255
            newurl = self.base
256
        else:
257
            newurl = urlutils.join(self.base, offset)
258
0.200.307 by Jelmer Vernooij
Support git+ssh.
259
        return self.__class__(newurl, self._client)
260
261
262
class TCPGitSmartTransport(GitSmartTransport):
263
0.200.332 by Jelmer Vernooij
Support activity reporting.
264
    _scheme = 'git'
265
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
266
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
267
        if self._client is not None:
268
            ret = self._client
269
            self._client = None
270
            return ret
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
271
        if self._host == '':
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
272
            # return dulwich.client.LocalGitClient()
273
            return dulwich.client.SubprocessGitClient()
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
274
        return dulwich.client.TCPGitClient(
275
            self._host, self._port, report_activity=self._report_activity)
0.200.307 by Jelmer Vernooij
Support git+ssh.
276
277
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
278
class SSHSocketWrapper(object):
279
280
    def __init__(self, sock):
281
        self.sock = sock
282
283
    def read(self, len=None):
284
        return self.sock.recv(len)
285
286
    def write(self, data):
287
        return self.sock.write(data)
288
289
    def can_read(self):
290
        return len(select.select([self.sock.fileno()], [], [], 0)[0]) > 0
291
292
293
class DulwichSSHVendor(dulwich.client.SSHVendor):
294
295
    def __init__(self):
6986.2.1 by Jelmer Vernooij
Move breezy.plugins.git to breezy.git.
296
        from ..transport import ssh
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
297
        self.bzr_ssh_vendor = ssh._get_ssh_vendor()
298
299
    def run_command(self, host, command, username=None, port=None):
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
300
        connection = self.bzr_ssh_vendor.connect_ssh(
301
            username=username, password=None, port=port, host=host,
302
            command=command)
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
303
        (kind, io_object) = connection.get_sock_or_pipes()
304
        if kind == 'socket':
305
            return SSHSocketWrapper(io_object)
306
        else:
307
            raise AssertionError("Unknown io object kind %r'" % kind)
308
309
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
310
# dulwich.client.get_ssh_vendor = DulwichSSHVendor
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
311
312
0.200.307 by Jelmer Vernooij
Support git+ssh.
313
class SSHGitSmartTransport(GitSmartTransport):
314
0.200.332 by Jelmer Vernooij
Support activity reporting.
315
    _scheme = 'git+ssh'
316
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
317
    def _get_path(self):
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
318
        path = self._stripped_path
0.200.1318 by Jelmer Vernooij
Strip segment parameters where necessary.
319
        if path.startswith("/~/"):
320
            return path[3:]
321
        return path
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
322
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
323
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
324
        if self._client is not None:
325
            ret = self._client
326
            self._client = None
327
            return ret
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
328
        location_config = config.LocationConfig(self.base)
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
329
        client = dulwich.client.SSHGitClient(
330
            self._host, self._port, self._username,
331
            report_activity=self._report_activity)
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
332
        # Set up alternate pack program paths
333
        upload_pack = location_config.get_user_option('git_upload_pack')
334
        if upload_pack:
0.200.949 by Jelmer Vernooij
merge support for specifying alternative paths for git executables.
335
            client.alternative_paths["upload-pack"] = upload_pack
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
336
        receive_pack = location_config.get_user_option('git_receive_pack')
337
        if receive_pack:
0.200.949 by Jelmer Vernooij
merge support for specifying alternative paths for git executables.
338
            client.alternative_paths["receive-pack"] = receive_pack
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
339
        return client
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
340
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
341
0.295.1 by Jelmer Vernooij
Split up branch formats.
342
class RemoteGitBranchFormat(GitBranchFormat):
343
344
    def get_format_description(self):
345
        return 'Remote Git Branch'
346
347
    @property
348
    def _matchingcontroldir(self):
349
        return RemoteGitControlDirFormat()
350
0.295.2 by Jelmer Vernooij
Make RemoteGitBranchFormat uninitializeable.
351
    def initialize(self, a_controldir, name=None, repository=None,
352
                   append_revisions_only=None):
353
        raise UninitializableFormat(self)
354
0.295.1 by Jelmer Vernooij
Split up branch formats.
355
0.407.1 by Jelmer Vernooij
Improve progress reporting.
356
class DefaultProgressReporter(object):
357
358
    _GIT_PROGRESS_PARTIAL_RE = re.compile(r"(.*?): +(\d+)% \((\d+)/(\d+)\)")
359
    _GIT_PROGRESS_TOTAL_RE = re.compile(r"(.*?): (\d+)")
360
361
    def __init__(self, pb):
362
        self.pb = pb
363
364
    def progress(self, text):
7018.3.2 by Jelmer Vernooij
Fix some git tests.
365
        text = text.rstrip(b"\r\n")
366
        text = text.decode('utf-8')
7131.7.1 by Jelmer Vernooij
Handle permission denied by GitLab.
367
        if text.lower().startswith('error: '):
7018.3.2 by Jelmer Vernooij
Fix some git tests.
368
            trace.show_error('git: %s', text[len(b'error: '):])
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
369
        else:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
370
            trace.mutter("git: %s", text)
371
            g = self._GIT_PROGRESS_PARTIAL_RE.match(text)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
372
            if g is not None:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
373
                (text, pct, current, total) = g.groups()
374
                self.pb.update(text, int(current), int(total))
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
375
            else:
0.407.1 by Jelmer Vernooij
Improve progress reporting.
376
                g = self._GIT_PROGRESS_TOTAL_RE.match(text)
377
                if g is not None:
378
                    (text, total) = g.groups()
379
                    self.pb.update(text, None, int(total))
380
                else:
381
                    trace.note("%s", text)
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
382
383
0.200.148 by Jelmer Vernooij
Share more infrastructure between LocalGitDir and RemoteGitDir.
384
class RemoteGitDir(GitDir):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
385
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
386
    def __init__(self, transport, format, client, client_path):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
387
        self._format = format
388
        self.root_transport = transport
389
        self.transport = transport
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
390
        self._mode_check_done = None
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
391
        self._client = client
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
392
        self._client_path = client_path
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
393
        self.base = self.root_transport.base
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
394
        self._refs = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
395
0.322.1 by Jelmer Vernooij
Fix access of remote git branches.
396
    @property
397
    def _gitrepository_class(self):
398
        return RemoteGitRepository
399
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
400
    def archive(self, format, committish, write_data, progress=None,
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
401
                write_error=None, subdirs=None, prefix=None):
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
402
        if progress is None:
403
            pb = ui.ui_factory.nested_progress_bar()
404
            progress = DefaultProgressReporter(pb).progress
405
        else:
406
            pb = None
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
407
        def progress_wrapper(message):
408
            if message.startswith(b"fatal: Unknown archive format \'"):
409
                format = message.strip()[len(b"fatal: Unknown archive format '"):-1]
410
                raise errors.NoSuchExportFormat(format.decode('ascii'))
411
            return progress(message)
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
412
        try:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
413
            self._client.archive(
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
414
                self._client_path, committish, write_data, progress_wrapper,
415
                write_error,
416
                format=(format.encode('ascii') if format else None),
417
                subdirs=subdirs,
418
                prefix=(prefix.encode('utf-8') if prefix else None))
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
419
        except GitProtocolError as e:
420
            raise parse_git_error(self.transport.external_url(), e)
421
        finally:
422
            if pb is not None:
423
                pb.finished()
424
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
425
    def fetch_pack(self, determine_wants, graph_walker, pack_data,
426
                   progress=None):
0.200.1335 by Jelmer Vernooij
Move _get_client.
427
        if progress is None:
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
428
            pb = ui.ui_factory.nested_progress_bar()
0.407.1 by Jelmer Vernooij
Improve progress reporting.
429
            progress = DefaultProgressReporter(pb).progress
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
430
        else:
431
            pb = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
432
        try:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
433
            result = self._client.fetch_pack(
434
                self._client_path, determine_wants, graph_walker, pack_data,
435
                progress)
0.376.1 by Jelmer Vernooij
Add tests for remote operations.
436
            if result.refs is None:
437
                result.refs = {}
7143.15.2 by Jelmer Vernooij
Run autopep8.
438
            self._refs = remote_refs_dict_to_container(
439
                result.refs, result.symrefs)
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
440
            return result
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
441
        except GitProtocolError as e:
0.200.1335 by Jelmer Vernooij
Move _get_client.
442
            raise parse_git_error(self.transport.external_url(), e)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
443
        finally:
444
            if pb is not None:
445
                pb.finished()
0.200.1335 by Jelmer Vernooij
Move _get_client.
446
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
447
    def send_pack(self, get_changed_refs, generate_pack_data, progress=None):
448
        if progress is None:
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
449
            pb = ui.ui_factory.nested_progress_bar()
0.407.1 by Jelmer Vernooij
Improve progress reporting.
450
            progress = DefaultProgressReporter(pb).progress
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
451
        else:
452
            pb = None
7143.15.2 by Jelmer Vernooij
Run autopep8.
453
0.419.1 by Jelmer Vernooij
Simplify pushing to Git directories.
454
        def get_changed_refs_wrapper(refs):
455
            # TODO(jelmer): This drops symref information
456
            self._refs = remote_refs_dict_to_container(refs)
457
            return get_changed_refs(refs)
0.200.1335 by Jelmer Vernooij
Move _get_client.
458
        try:
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
459
            return self._client.send_pack(
460
                self._client_path, get_changed_refs_wrapper,
461
                generate_pack_data, progress)
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
462
        except GitProtocolError as e:
0.200.1335 by Jelmer Vernooij
Move _get_client.
463
            raise parse_git_error(self.transport.external_url(), e)
0.405.1 by Jelmer Vernooij
Use same logic for interpreting progress reports everywhere.
464
        finally:
465
            if pb is not None:
466
                pb.finished()
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
467
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
468
    def create_branch(self, name=None, repository=None,
469
                      append_revisions_only=None, ref=None):
470
        refname = self._get_selected_ref(name, ref)
471
        if refname != b'HEAD' and refname in self.get_refs_container():
472
            raise AlreadyBranchError(self.user_url)
473
        if refname in self.get_refs_container():
7143.15.2 by Jelmer Vernooij
Run autopep8.
474
            ref_chain, unused_sha = self.get_refs_container().follow(
475
                self._get_selected_ref(None))
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
476
            if ref_chain[0] == b'HEAD':
477
                refname = ref_chain[1]
478
        repo = self.open_repository()
479
        return RemoteGitBranch(self, repo, refname)
480
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
481
    def destroy_branch(self, name=None):
482
        refname = self._get_selected_ref(name)
7143.15.2 by Jelmer Vernooij
Run autopep8.
483
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
484
        def get_changed_refs(old_refs):
7240.3.1 by Jelmer Vernooij
When sending refs to a remote server, don't send a copy of the old refs.
485
            ret = {}
7240.3.2 by Jelmer Vernooij
Fix tests.
486
            if refname not in old_refs:
0.200.1395 by Jelmer Vernooij
Fix error reporting.
487
                raise NotBranchError(self.user_url)
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
488
            ret[refname] = dulwich.client.ZERO_SHA
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
489
            return ret
7143.15.2 by Jelmer Vernooij
Run autopep8.
490
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
491
        def generate_pack_data(have, want, ofs_delta=False):
492
            return pack_objects_to_data([])
493
        self.send_pack(get_changed_refs, generate_pack_data)
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
494
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
495
    @property
496
    def user_url(self):
497
        return self.control_url
498
0.200.1314 by Jelmer Vernooij
Provide RemoteGitDir.user_transport.
499
    @property
500
    def user_transport(self):
501
        return self.root_transport
502
0.200.1395 by Jelmer Vernooij
Fix error reporting.
503
    @property
504
    def control_url(self):
505
        return self.control_transport.base
506
507
    @property
508
    def control_transport(self):
509
        return self.root_transport
510
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
511
    def open_repository(self):
0.200.1415 by Jelmer Vernooij
Fix lock files for remote directories.
512
        return RemoteGitRepository(self)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
513
7142.3.1 by Jelmer Vernooij
Support .nick on remote branches and fix get_branch_reference.
514
    def get_branch_reference(self, name=None):
515
        ref = branch_name_to_ref(name)
516
        val = self.get_refs_container().read_ref(ref)
517
        if val.startswith(SYMREF):
518
            return val[len(SYMREF):]
519
        return None
520
0.200.1310 by Jelmer Vernooij
Add _get_selected_ref method.
521
    def open_branch(self, name=None, unsupported=False,
7143.15.2 by Jelmer Vernooij
Run autopep8.
522
                    ignore_fallbacks=False, ref=None, possible_transports=None,
523
                    nascent_ok=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
524
        repo = self.open_repository()
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
525
        ref = self._get_selected_ref(name, ref)
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
526
        try:
527
            if not nascent_ok and ref not in self.get_refs_container():
7143.16.10 by Jelmer Vernooij
Fix E128.
528
                raise NotBranchError(
529
                    self.root_transport.base, controldir=self)
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
530
        except NotGitRepository:
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
531
            raise NotBranchError(self.root_transport.base,
7143.15.2 by Jelmer Vernooij
Run autopep8.
532
                                 controldir=self)
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
533
        ref_chain, unused_sha = self.get_refs_container().follow(ref)
534
        return RemoteGitBranch(self, repo, ref_chain[-1])
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
535
0.200.662 by Jelmer Vernooij
Deal with recommend_upgrade argument to open_workingtree.
536
    def open_workingtree(self, recommend_upgrade=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
537
        raise NotLocalUrl(self.transport.base)
538
0.310.4 by Jelmer Vernooij
Implement RemoteControlDir.has_workingtree.
539
    def has_workingtree(self):
540
        return False
541
0.200.1489 by Jelmer Vernooij
More fixes to peel handling.
542
    def get_peeled(self, name):
543
        return self.get_refs_container().get_peeled(name)
544
0.200.1487 by Jelmer Vernooij
Use peeling.
545
    def get_refs_container(self):
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
546
        if self._refs is not None:
547
            return self._refs
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
548
        result = self.fetch_pack(lambda x: None, None,
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
549
                                 lambda x: None,
550
                                 lambda x: trace.mutter("git: %s" % x))
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
551
        self._refs = remote_refs_dict_to_container(
7143.15.2 by Jelmer Vernooij
Run autopep8.
552
            result.refs, result.symrefs)
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
553
        return self._refs
554
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
555
    def push_branch(self, source, revision_id=None, overwrite=False,
556
                    remember=False, create_prefix=False, lossy=False,
557
                    name=None):
558
        """Push the source branch into this ControlDir."""
559
        if revision_id is None:
560
            # No revision supplied by the user, default to the branch
561
            # revision
562
            revision_id = source.last_revision()
563
0.406.1 by Jelmer Vernooij
Properly lookup revnos for brz-git push result.
564
        push_result = GitPushResult()
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
565
        push_result.workingtree_updated = None
566
        push_result.master_branch = None
567
        push_result.source_branch = source
568
        push_result.stacked_on = None
569
        push_result.branch_push_result = None
570
        repo = self.find_repository()
571
        refname = self._get_selected_ref(name)
0.407.1 by Jelmer Vernooij
Improve progress reporting.
572
        if isinstance(source, GitBranch) and lossy:
573
            raise errors.LossyPushToSameVCS(source.controldir, self)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
574
        source_store = get_object_store(source.repository)
7289.1.2 by Jelmer Vernooij
Fix pushing of tags as part of nascent git branches.
575
        fetch_tags = source.get_config_stack().get('branch.fetch_tags')
576
        def get_changed_refs(refs):
577
            self._refs = remote_refs_dict_to_container(refs)
578
            ret = {}
579
            # TODO(jelmer): Unpeel if necessary
580
            push_result.new_original_revid = revision_id
581
            if lossy:
582
                new_sha = source_store._lookup_revision_sha1(revision_id)
583
            else:
584
                try:
585
                    new_sha = repo.lookup_bzr_revision_id(revision_id)[0]
586
                except errors.NoSuchRevision:
587
                    raise errors.NoRoundtrippingSupport(
588
                        source, self.open_branch(name=name, nascent_ok=True))
589
            if not overwrite:
590
                if remote_divergence(ret.get(refname), new_sha,
591
                                     source_store):
592
                    raise DivergedBranches(
593
                        source, self.open_branch(name, nascent_ok=True))
594
            ret[refname] = new_sha
595
            if fetch_tags:
7289.1.5 by Jelmer Vernooij
Fix flake8 warning.
596
                for tagname, revid in viewitems(source.tags.get_tag_dict()):
7289.1.2 by Jelmer Vernooij
Fix pushing of tags as part of nascent git branches.
597
                    if lossy:
598
                        new_sha = source_store._lookup_revision_sha1(revid)
599
                    else:
600
                        try:
601
                            new_sha = repo.lookup_bzr_revision_id(revid)[0]
602
                        except errors.NoSuchRevision:
603
                            continue
7289.1.5 by Jelmer Vernooij
Fix flake8 warning.
604
                    ret[tag_name_to_ref(tagname)] = new_sha
7289.1.2 by Jelmer Vernooij
Fix pushing of tags as part of nascent git branches.
605
            return ret
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
606
        with source_store.lock_read():
607
            if lossy:
608
                generate_pack_data = source_store.generate_lossy_pack_data
609
            else:
610
                generate_pack_data = source_store.generate_pack_data
611
            new_refs = self.send_pack(get_changed_refs, generate_pack_data)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
612
        push_result.new_revid = repo.lookup_foreign_revision_id(
7143.15.2 by Jelmer Vernooij
Run autopep8.
613
            new_refs[refname])
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
614
        try:
615
            old_remote = self._refs[refname]
616
        except KeyError:
617
            old_remote = ZERO_SHA
618
        push_result.old_revid = repo.lookup_foreign_revision_id(old_remote)
619
        self._refs = remote_refs_dict_to_container(new_refs)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
620
        push_result.target_branch = self.open_branch(name)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
621
        if old_remote != ZERO_SHA:
622
            push_result.branch_push_result = GitBranchPushResult()
623
            push_result.branch_push_result.source_branch = source
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
624
            push_result.branch_push_result.target_branch = (
625
                push_result.target_branch)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
626
            push_result.branch_push_result.local_branch = None
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
627
            push_result.branch_push_result.master_branch = (
628
                push_result.target_branch)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
629
            push_result.branch_push_result.old_revid = push_result.old_revid
630
            push_result.branch_push_result.new_revid = push_result.new_revid
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
631
            push_result.branch_push_result.new_original_revid = (
632
                push_result.new_original_revid)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
633
        if source.get_push_location() is None or remember:
634
            source.set_push_location(push_result.target_branch.base)
635
        return push_result
636
0.409.1 by Jelmer Vernooij
Don't probe for commondir over remote transport.
637
    def _find_commondir(self):
638
        # There is no way to find the commondir, if there is any.
639
        return self
640
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
641
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
642
class EmptyObjectStoreIterator(dict):
643
644
    def iterobjects(self):
645
        return []
646
647
0.200.218 by Jelmer Vernooij
Simplify TemporaryPack implementation.
648
class TemporaryPackIterator(Pack):
649
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
650
    def __init__(self, path, resolve_ext_ref):
0.279.1 by William Grant
Support thin packs in fetch_pack and send_pack, since dulwich now handles them properly.
651
        super(TemporaryPackIterator, self).__init__(
652
            path, resolve_ext_ref=resolve_ext_ref)
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
653
        self._idx_load = lambda: self._idx_load_or_generate(self._idx_path)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
654
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
655
    def _idx_load_or_generate(self, path):
656
        if not os.path.exists(path):
7143.22.2 by Jelmer Vernooij
use more context libs for progress bars.
657
            with ui.ui_factory.nested_progress_bar() as pb:
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
658
                def report_progress(cur, total):
659
                    pb.update("generating index", cur, total)
7143.22.3 by Jelmer Vernooij
merge trunk.
660
                self.data.create_index(path, progress=report_progress)
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
661
        return load_pack_index(path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
662
663
    def __del__(self):
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
664
        if self._idx is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
665
            self._idx.close()
666
            os.remove(self._idx_path)
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
667
        if self._data is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
668
            self._data.close()
669
            os.remove(self._data_path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
670
671
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
672
class BzrGitHttpClient(dulwich.client.HttpGitClient):
673
674
    def __init__(self, transport, *args, **kwargs):
675
        self.transport = transport
7268.10.2 by Jelmer Vernooij
Strip username.
676
        url = urlutils.URL.from_string(transport.external_url())
677
        url.user = url.quoted_user = None
678
        url.password = url.quoted_password = None
7371.3.2 by Jelmer Vernooij
Fix URL parsing for Git.
679
        url = urlutils.split_segment_parameters(str(url))[0]
680
        super(BzrGitHttpClient, self).__init__(url, *args, **kwargs)
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
681
682
    def _http_request(self, url, headers=None, data=None,
683
                      allow_compression=False):
684
        """Perform HTTP request.
685
686
        :param url: Request URL.
687
        :param headers: Optional custom headers to override defaults.
688
        :param data: Request data.
689
        :param allow_compression: Allow GZipped communication.
690
        :return: Tuple (`response`, `read`), where response is an `urllib3`
7140.1.1 by Jelmer Vernooij
Rollback https://code.launchpad.net/~jelmer/brz/python3-git-fix-http/+merge/356238
691
            response object with additional `content_type` and
692
            `redirect_location` properties, and `read` is a consumable read
693
            method for the response data.
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
694
        """
7359.1.1 by Jelmer Vernooij
Only set user agent for GitHub.
695
        if is_github_url(url):
696
            headers['User-agent'] = user_agent_for_github()
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
697
        headers["Pragma"] = "no-cache"
698
        if allow_compression:
699
            headers["Accept-Encoding"] = "gzip"
700
        else:
701
            headers["Accept-Encoding"] = "identity"
702
7296.2.2 by Jelmer Vernooij
Add a urllib3-like interface.
703
        response = self.transport.request(
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
704
            ('GET' if data is None else 'POST'),
7320.1.1 by Jelmer Vernooij
Fix git http support.
705
            url,
7296.2.2 by Jelmer Vernooij
Add a urllib3-like interface.
706
            body=data,
707
            headers=headers, retries=8)
708
709
        if response.status == 404:
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
710
            raise NotGitRepository()
7296.2.2 by Jelmer Vernooij
Add a urllib3-like interface.
711
        elif response.status != 200:
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
712
            raise GitProtocolError("unexpected http resp %d for %s" %
713
                                   (response.code, url))
714
715
        # TODO: Optimization available by adding `preload_content=False` to the
716
        # request and just passing the `read` method on instead of going via
717
        # `BytesIO`, if we can guarantee that the entire response is consumed
718
        # before issuing the next to still allow for connection reuse from the
719
        # pool.
720
        if response.getheader("Content-Encoding") == "gzip":
721
            read = gzip.GzipFile(fileobj=response).read
722
        else:
723
            read = response.read
724
725
        class WrapResponse(object):
726
727
            def __init__(self, response):
728
                self._response = response
7320.1.1 by Jelmer Vernooij
Fix git http support.
729
                self.status = response.status
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
730
                self.content_type = response.getheader("Content-Type")
7320.1.1 by Jelmer Vernooij
Fix git http support.
731
                self.redirect_location = response._actual.geturl()
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
732
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
733
            def readlines(self):
734
                return self._response.readlines()
735
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
736
            def close(self):
7320.1.1 by Jelmer Vernooij
Fix git http support.
737
                pass
0.409.2 by Jelmer Vernooij
call out to HTTP transport rather than creating new connection.
738
739
        return WrapResponse(response), read
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
740
741
7371.3.2 by Jelmer Vernooij
Fix URL parsing for Git.
742
def _git_url_and_path_from_transport(external_url):
7371.3.3 by Jelmer Vernooij
Fix tests.
743
    url, _ = urlutils.split_segment_parameters(external_url)
7371.3.2 by Jelmer Vernooij
Fix URL parsing for Git.
744
    return urlparse.urlsplit(url)
745
746
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
747
class RemoteGitControlDirFormat(GitControlDirFormat):
748
    """The .git directory control format."""
749
750
    supports_workingtrees = False
751
752
    @classmethod
753
    def _known_formats(self):
754
        return set([RemoteGitControlDirFormat()])
755
0.295.1 by Jelmer Vernooij
Split up branch formats.
756
    def get_branch_format(self):
757
        return RemoteGitBranchFormat()
758
7290.20.3 by Jelmer Vernooij
Fix tests for git/full history branches.
759
    @property
760
    def repository_format(self):
761
        return GitRepositoryFormat()
762
0.200.1413 by Jelmer Vernooij
Fix is_initializable()
763
    def is_initializable(self):
764
        return False
765
766
    def is_supported(self):
767
        return True
768
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
769
    def open(self, transport, _found=None):
770
        """Open this directory.
771
772
        """
7371.3.2 by Jelmer Vernooij
Fix URL parsing for Git.
773
        split_url = _git_url_and_path_from_transport(transport.external_url())
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
774
        if isinstance(transport, GitSmartTransport):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
775
            client = transport._get_client()
7371.3.2 by Jelmer Vernooij
Fix URL parsing for Git.
776
        elif split_url.scheme in ("http", "https"):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
777
            client = BzrGitHttpClient(transport)
7380.1.1 by Jelmer Vernooij
Several more fixes for git merge proposals.
778
        elif split_url.scheme in ('file', ):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
779
            client = dulwich.client.LocalGitClient()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
780
        else:
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
781
            raise NotBranchError(transport.base)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
782
        if not _found:
7143.15.2 by Jelmer Vernooij
Run autopep8.
783
            pass  # TODO(jelmer): Actually probe for something
7371.3.2 by Jelmer Vernooij
Fix URL parsing for Git.
784
        return RemoteGitDir(transport, self, client, split_url.path)
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
785
786
    def get_format_description(self):
787
        return "Remote Git Repository"
788
789
    def initialize_on_transport(self, transport):
790
        raise UninitializableFormat(self)
791
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
792
    def supports_transport(self, transport):
793
        try:
794
            external_url = transport.external_url()
795
        except InProcessTransport:
796
            raise NotBranchError(path=transport.base)
7143.15.2 by Jelmer Vernooij
Run autopep8.
797
        return (external_url.startswith("http:")
798
                or external_url.startswith("https:")
799
                or external_url.startswith("git+")
800
                or external_url.startswith("git:"))
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
801
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
802
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
803
class GitRemoteRevisionTree(RevisionTree):
804
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
805
    def archive(self, format, name, root=None, subdir=None, force_mtime=None):
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
806
        """Create an archive of this tree.
807
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
808
        :param format: Format name (e.g. 'tar')
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
809
        :param name: target file name
810
        :param root: Root directory name (or None)
811
        :param subdir: Subdirectory to export (or None)
812
        :return: Iterator over archive chunks
813
        """
814
        commit = self._repository.lookup_bzr_revision_id(
815
            self.get_revision_id())[0]
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
816
        f = tempfile.SpooledTemporaryFile()
817
        # git-upload-archive(1) generaly only supports refs. So let's see if we
818
        # can find one.
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
819
        reverse_refs = {
7143.15.2 by Jelmer Vernooij
Run autopep8.
820
            v: k for (k, v) in
821
            self._repository.controldir.get_refs_container().as_dict().items()}
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
822
        try:
823
            committish = reverse_refs[commit]
824
        except KeyError:
825
            # No? Maybe the user has uploadArchive.allowUnreachable enabled.
826
            # Let's hope for the best.
827
            committish = commit
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
828
        self._repository.archive(
7143.15.2 by Jelmer Vernooij
Run autopep8.
829
            format, committish, f.write,
830
            subdirs=([subdir] if subdir else None),
831
            prefix=(root + '/') if root else '')
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
832
        f.seek(0)
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
833
        return osutils.file_iterator(f)
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
834
7192.5.1 by Jelmer Vernooij
Remove more file ids.
835
    def is_versioned(self, path):
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
836
        raise GitSmartRemoteNotSupported(self.is_versioned, self)
837
838
    def has_filename(self, path):
839
        raise GitSmartRemoteNotSupported(self.has_filename, self)
840
7192.5.1 by Jelmer Vernooij
Remove more file ids.
841
    def get_file_text(self, path):
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
842
        raise GitSmartRemoteNotSupported(self.get_file_text, self)
843
7413.4.4 by Jelmer Vernooij
'Implement' RevisionTree.list_files.
844
    def list_files(self, include_root=False, from_dir=None, recursive=True):
845
        raise GitSmartRemoteNotSupported(self.list_files, self)
846
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
847
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
848
class RemoteGitRepository(GitRepository):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
849
7254.5.1 by Jelmer Vernooij
Add supports_random_access attribute to repositories.
850
    supports_random_access = False
851
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
852
    @property
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
853
    def user_url(self):
854
        return self.control_url
855
0.200.1288 by Jelmer Vernooij
Properly raise GitRemoteNotSupported from RemoteGitRepository.
856
    def get_parent_map(self, revids):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
857
        raise GitSmartRemoteNotSupported(self.get_parent_map, self)
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
858
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
859
    def archive(self, *args, **kwargs):
860
        return self.controldir.archive(*args, **kwargs)
861
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
862
    def fetch_pack(self, determine_wants, graph_walker, pack_data,
0.200.155 by Jelmer Vernooij
Fix formatting, remove catch-all for exceptions when opening local repositories.
863
                   progress=None):
7143.2.1 by Jelmer Vernooij
Don't hardcode the list of supported archive formats.
864
        return self.controldir.fetch_pack(
7143.16.8 by Jelmer Vernooij
Fix E126
865
            determine_wants, graph_walker, pack_data, progress)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
866
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
867
    def send_pack(self, get_changed_refs, generate_pack_data):
868
        return self.controldir.send_pack(get_changed_refs, generate_pack_data)
0.200.427 by Jelmer Vernooij
make send_pack accessible.
869
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
870
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
871
                      progress=None):
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
872
        fd, path = tempfile.mkstemp(suffix=".pack")
0.200.1299 by Jelmer Vernooij
Make sure file gets closed.
873
        try:
874
            self.fetch_pack(determine_wants, graph_walker,
7143.15.2 by Jelmer Vernooij
Run autopep8.
875
                            lambda x: os.write(fd, x), progress)
0.200.1299 by Jelmer Vernooij
Make sure file gets closed.
876
        finally:
877
            os.close(fd)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
878
        if os.path.getsize(path) == 0:
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
879
            return EmptyObjectStoreIterator()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
880
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
881
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
882
    def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
7143.15.3 by Jelmer Vernooij
Fix pep8 issues in breezy.git.
883
        # This won't work for any round-tripped bzr revisions, but it's a
884
        # start..
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
885
        try:
886
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
887
        except InvalidRevisionId:
888
            raise NoSuchRevision(self, bzr_revid)
889
0.252.48 by Jelmer Vernooij
Implement lookup_foreign_revision for remote branches.
890
    def lookup_foreign_revision_id(self, foreign_revid, mapping=None):
891
        """Lookup a revision id.
892
893
        """
894
        if mapping is None:
895
            mapping = self.get_mapping()
896
        # Not really an easy way to parse foreign revids here..
897
        return mapping.revision_id_foreign_to_bzr(foreign_revid)
898
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
899
    def revision_tree(self, revid):
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
900
        return GitRemoteRevisionTree(self, revid)
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
901
0.200.1481 by Jelmer Vernooij
'Implement' RemoteGitRepository.get_revisions.
902
    def get_revisions(self, revids):
903
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
904
0.200.1557 by Jelmer Vernooij
Implement RemoteGitRepository.has_revisions.
905
    def has_revisions(self, revids):
906
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
907
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
908
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
909
class RemoteGitTagDict(GitTags):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
910
911
    def set_tag(self, name, revid):
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
912
        sha = self.branch.lookup_bzr_revision_id(revid)[0]
913
        self._set_ref(name, sha)
914
915
    def delete_tag(self, name):
916
        self._set_ref(name, dulwich.client.ZERO_SHA)
917
918
    def _set_ref(self, name, sha):
919
        ref = tag_name_to_ref(name)
7143.15.2 by Jelmer Vernooij
Run autopep8.
920
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
921
        def get_changed_refs(old_refs):
7240.3.1 by Jelmer Vernooij
When sending refs to a remote server, don't send a copy of the old refs.
922
            ret = {}
7240.3.2 by Jelmer Vernooij
Fix tests.
923
            if sha == dulwich.client.ZERO_SHA and ref not in old_refs:
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
924
                raise NoSuchTag(name)
925
            ret[ref] = sha
926
            return ret
7143.15.2 by Jelmer Vernooij
Run autopep8.
927
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
928
        def generate_pack_data(have, want, ofs_delta=False):
929
            return pack_objects_to_data([])
930
        self.repository.send_pack(get_changed_refs, generate_pack_data)
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
931
932
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
933
class RemoteGitBranch(GitBranch):
934
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
935
    def __init__(self, controldir, repository, name):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
936
        self._sha = None
0.295.1 by Jelmer Vernooij
Split up branch formats.
937
        super(RemoteGitBranch, self).__init__(controldir, repository, name,
7143.15.2 by Jelmer Vernooij
Run autopep8.
938
                                              RemoteGitBranchFormat())
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
939
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
940
    def last_revision_info(self):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
941
        raise GitSmartRemoteNotSupported(self.last_revision_info, self)
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
942
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
943
    @property
944
    def user_url(self):
945
        return self.control_url
946
947
    @property
948
    def control_url(self):
949
        return self.base
950
0.200.1436 by Jelmer Vernooij
Raise UnsupportedOperation for `Branch.revision_id_to_dotted_revno`,
951
    def revision_id_to_revno(self, revision_id):
952
        raise GitSmartRemoteNotSupported(self.revision_id_to_revno, self)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
953
954
    def last_revision(self):
0.252.44 by Jelmer Vernooij
Properly look up Bazaar revision ids for revision parents in case they are round-tripped.
955
        return self.lookup_foreign_revision_id(self.head)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
956
957
    @property
958
    def head(self):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
959
        if self._sha is not None:
960
            return self._sha
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
961
        refs = self.controldir.get_refs_container()
0.200.1561 by Jelmer Vernooij
Some fixes for colocated branch handling.
962
        name = branch_name_to_ref(self.name)
0.200.1386 by Jelmer Vernooij
Friendlier message if HEAD is not found.
963
        try:
964
            self._sha = refs[name]
965
        except KeyError:
966
            raise NoSuchRef(name, self.repository.user_url, refs)
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
967
        return self._sha
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
968
0.200.169 by Jelmer Vernooij
Fix branch cloning.
969
    def _synchronize_history(self, destination, revision_id):
970
        """See Branch._synchronize_history()."""
7143.12.1 by Jelmer Vernooij
Support cloning revisions referenced only by an annotated tag.
971
        if revision_id is None:
972
            revision_id = self.last_revision()
973
        destination.generate_revision_history(revision_id)
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
974
0.289.1 by Jelmer Vernooij
No parent location for remote repos.
975
    def _get_parent_location(self):
976
        return None
977
0.200.499 by Jelmer Vernooij
Implement RemoteBranch.{get,set}_push_location.
978
    def get_push_location(self):
979
        return None
980
981
    def set_push_location(self, url):
982
        pass
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
983
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
984
    def _iter_tag_refs(self):
985
        """Iterate over the tag refs.
986
987
        :param refs: Refs dictionary (name -> git sha1)
988
        :return: iterator over (ref_name, tag_name, peeled_sha1, unpeeled_sha1)
989
        """
990
        refs = self.controldir.get_refs_container()
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
991
        for ref_name, unpeeled in refs.as_dict().items():
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
992
            try:
993
                tag_name = ref_to_tag_name(ref_name)
994
            except (ValueError, UnicodeDecodeError):
995
                continue
996
            peeled = refs.get_peeled(ref_name)
997
            if peeled is None:
7058.4.36 by Jelmer Vernooij
Fix peeled error.
998
                # Let's just hope it's a commit
999
                peeled = unpeeled
6973.6.2 by Jelmer Vernooij
Fix more tests.
1000
            if not isinstance(tag_name, text_type):
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
1001
                raise TypeError(tag_name)
1002
            yield (ref_name, tag_name, peeled, unpeeled)
1003
7131.12.1 by Jelmer Vernooij
Support uncommit on remote git branches.
1004
    def set_last_revision_info(self, revno, revid):
1005
        self.generate_revision_history(revid)
1006
1007
    def generate_revision_history(self, revision_id, last_rev=None,
1008
                                  other_branch=None):
1009
        sha = self.lookup_bzr_revision_id(revision_id)[0]
1010
        def get_changed_refs(old_refs):
1011
            return {self.ref: sha}
1012
        def generate_pack_data(have, want, ofs_delta=False):
1013
            return pack_objects_to_data([])
1014
        self.repository.send_pack(get_changed_refs, generate_pack_data)
1015
        self._sha = sha
1016
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
1017
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
1018
def remote_refs_dict_to_container(refs_dict, symrefs_dict={}):
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
1019
    base = {}
1020
    peeled = {}
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
1021
    for k, v in refs_dict.items():
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
1022
        if is_peeled(k):
1023
            peeled[k[:-3]] = v
1024
        else:
1025
            base[k] = v
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
1026
    for name, target in symrefs_dict.items():
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
1027
        base[name] = SYMREF + target
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
1028
    ret = DictRefsContainer(base)
1029
    ret._peeled = peeled
1030
    return ret