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