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