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