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