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