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