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