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