/brz/remove-bazaar

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