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