/brz/remove-bazaar

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