/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])
647
648
        response = self.transport._perform(request)
649
650
        if response.code == 404:
651
            raise NotGitRepository()
652
        elif response.code != 200:
653
            raise GitProtocolError("unexpected http resp %d for %s" %
654
                                   (response.code, url))
655
656
        # TODO: Optimization available by adding `preload_content=False` to the
657
        # request and just passing the `read` method on instead of going via
658
        # `BytesIO`, if we can guarantee that the entire response is consumed
659
        # before issuing the next to still allow for connection reuse from the
660
        # pool.
661
        if response.getheader("Content-Encoding") == "gzip":
662
            read = gzip.GzipFile(fileobj=response).read
663
        else:
664
            read = response.read
665
666
        class WrapResponse(object):
667
668
            def __init__(self, response):
669
                self._response = response
670
                self.status = response.code
671
                self.content_type = response.getheader("Content-Type")
672
                self.redirect_location = response.geturl()
673
674
            def close(self):
675
                self._response.close()
676
677
        return WrapResponse(response), read
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
678
679
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
680
class RemoteGitControlDirFormat(GitControlDirFormat):
681
    """The .git directory control format."""
682
683
    supports_workingtrees = False
684
685
    @classmethod
686
    def _known_formats(self):
687
        return set([RemoteGitControlDirFormat()])
688
0.295.1 by Jelmer Vernooij
Split up branch formats.
689
    def get_branch_format(self):
690
        return RemoteGitBranchFormat()
691
0.200.1413 by Jelmer Vernooij
Fix is_initializable()
692
    def is_initializable(self):
693
        return False
694
695
    def is_supported(self):
696
        return True
697
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
698
    def open(self, transport, _found=None):
699
        """Open this directory.
700
701
        """
702
        # we dont grok readonly - git isn't integrated with transport.
703
        url = transport.base
704
        if url.startswith('readonly+'):
705
            url = url[len('readonly+'):]
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
706
        scheme = urlparse.urlsplit(transport.external_url())[0]
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
707
        if isinstance(transport, GitSmartTransport):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
708
            client = transport._get_client()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
709
            client_path = transport._get_path()
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
710
        elif scheme in ("http", "https"):
711
            client = BzrGitHttpClient(transport)
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
712
            client_path, _ = urlutils.split_segment_parameters(transport._path)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
713
        elif scheme == 'file':
714
            client = dulwich.client.LocalGitClient()
715
            client_path = transport.local_abspath('.')
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
716
        else:
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
717
            raise NotBranchError(transport.base)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
718
        if not _found:
719
            pass # TODO(jelmer): Actually probe for something
720
        return RemoteGitDir(transport, self, client, client_path)
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
721
722
    def get_format_description(self):
723
        return "Remote Git Repository"
724
725
    def initialize_on_transport(self, transport):
726
        raise UninitializableFormat(self)
727
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
728
    def supports_transport(self, transport):
729
        try:
730
            external_url = transport.external_url()
731
        except InProcessTransport:
732
            raise NotBranchError(path=transport.base)
733
        return (external_url.startswith("http:") or
734
                external_url.startswith("https:") or
735
                external_url.startswith("git+") or
736
                external_url.startswith("git:"))
737
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
738
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
739
class GitRemoteRevisionTree(RevisionTree):
740
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
741
    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.
742
        """Create an archive of this tree.
743
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
744
        :param format: Format name (e.g. 'tar')
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
745
        :param name: target file name
746
        :param root: Root directory name (or None)
747
        :param subdir: Subdirectory to export (or None)
748
        :return: Iterator over archive chunks
749
        """
750
        commit = self._repository.lookup_bzr_revision_id(
751
            self.get_revision_id())[0]
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
752
        f = tempfile.SpooledTemporaryFile()
753
        # git-upload-archive(1) generaly only supports refs. So let's see if we
754
        # can find one.
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
755
        reverse_refs = {
756
                v: k for (k, v) in
757
                self._repository.controldir.get_refs_container().as_dict().items()}
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
758
        try:
759
            committish = reverse_refs[commit]
760
        except KeyError:
761
            # No? Maybe the user has uploadArchive.allowUnreachable enabled.
762
            # Let's hope for the best.
763
            committish = commit
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
764
        self._repository.archive(
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
765
                format, committish, f.write,
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
766
                subdirs=([subdir] if subdir else None),
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
767
                prefix=(root+'/') if root else '')
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
768
        f.seek(0)
6968.4.4 by Jelmer Vernooij
Update for API changes from archive branch.
769
        return osutils.file_iterator(f)
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
770
771
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
772
class RemoteGitRepository(GitRepository):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
773
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
774
    @property
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
775
    def user_url(self):
776
        return self.control_url
777
0.200.1288 by Jelmer Vernooij
Properly raise GitRemoteNotSupported from RemoteGitRepository.
778
    def get_parent_map(self, revids):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
779
        raise GitSmartRemoteNotSupported(self.get_parent_map, self)
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
780
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
781
    def archive(self, *args, **kwargs):
782
        return self.controldir.archive(*args, **kwargs)
783
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
784
    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.
785
                   progress=None):
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
786
        return self.controldir.fetch_pack(determine_wants, graph_walker,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
787
                                          pack_data, progress)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
788
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
789
    def send_pack(self, get_changed_refs, generate_pack_data):
790
        return self.controldir.send_pack(get_changed_refs, generate_pack_data)
0.200.427 by Jelmer Vernooij
make send_pack accessible.
791
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
792
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
793
                      progress=None):
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
794
        fd, path = tempfile.mkstemp(suffix=".pack")
0.200.1299 by Jelmer Vernooij
Make sure file gets closed.
795
        try:
796
            self.fetch_pack(determine_wants, graph_walker,
797
                lambda x: os.write(fd, x), progress)
798
        finally:
799
            os.close(fd)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
800
        if os.path.getsize(path) == 0:
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
801
            return EmptyObjectStoreIterator()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
802
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
803
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
804
    def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
805
        # This won't work for any round-tripped bzr revisions, but it's a start..
806
        try:
807
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
808
        except InvalidRevisionId:
809
            raise NoSuchRevision(self, bzr_revid)
810
0.252.48 by Jelmer Vernooij
Implement lookup_foreign_revision for remote branches.
811
    def lookup_foreign_revision_id(self, foreign_revid, mapping=None):
812
        """Lookup a revision id.
813
814
        """
815
        if mapping is None:
816
            mapping = self.get_mapping()
817
        # Not really an easy way to parse foreign revids here..
818
        return mapping.revision_id_foreign_to_bzr(foreign_revid)
819
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
820
    def revision_tree(self, revid):
6968.4.1 by Jelmer Vernooij
Add support for exporting archives in Git.
821
        return GitRemoteRevisionTree(self, revid)
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
822
0.200.1481 by Jelmer Vernooij
'Implement' RemoteGitRepository.get_revisions.
823
    def get_revisions(self, revids):
824
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
825
0.200.1557 by Jelmer Vernooij
Implement RemoteGitRepository.has_revisions.
826
    def has_revisions(self, revids):
827
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
828
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
829
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
830
class RemoteGitTagDict(GitTags):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
831
832
    def set_tag(self, name, revid):
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
833
        sha = self.branch.lookup_bzr_revision_id(revid)[0]
834
        self._set_ref(name, sha)
835
836
    def delete_tag(self, name):
837
        self._set_ref(name, dulwich.client.ZERO_SHA)
838
839
    def _set_ref(self, name, sha):
840
        ref = tag_name_to_ref(name)
841
        def get_changed_refs(old_refs):
842
            ret = dict(old_refs)
843
            if sha == dulwich.client.ZERO_SHA and ref not in ret:
844
                raise NoSuchTag(name)
845
            ret[ref] = sha
846
            return ret
847
        def generate_pack_data(have, want, ofs_delta=False):
848
            return pack_objects_to_data([])
849
        self.repository.send_pack(get_changed_refs, generate_pack_data)
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
850
851
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
852
class RemoteGitBranch(GitBranch):
853
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
854
    def __init__(self, controldir, repository, name):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
855
        self._sha = None
0.295.1 by Jelmer Vernooij
Split up branch formats.
856
        super(RemoteGitBranch, self).__init__(controldir, repository, name,
857
                RemoteGitBranchFormat())
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
858
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
859
    def last_revision_info(self):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
860
        raise GitSmartRemoteNotSupported(self.last_revision_info, self)
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
861
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
862
    @property
863
    def user_url(self):
864
        return self.control_url
865
866
    @property
867
    def control_url(self):
868
        return self.base
869
0.200.1436 by Jelmer Vernooij
Raise UnsupportedOperation for `Branch.revision_id_to_dotted_revno`,
870
    def revision_id_to_revno(self, revision_id):
871
        raise GitSmartRemoteNotSupported(self.revision_id_to_revno, self)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
872
873
    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.
874
        return self.lookup_foreign_revision_id(self.head)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
875
876
    @property
877
    def head(self):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
878
        if self._sha is not None:
879
            return self._sha
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
880
        refs = self.controldir.get_refs_container()
0.200.1561 by Jelmer Vernooij
Some fixes for colocated branch handling.
881
        name = branch_name_to_ref(self.name)
0.200.1386 by Jelmer Vernooij
Friendlier message if HEAD is not found.
882
        try:
883
            self._sha = refs[name]
884
        except KeyError:
885
            raise NoSuchRef(name, self.repository.user_url, refs)
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
886
        return self._sha
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
887
0.200.169 by Jelmer Vernooij
Fix branch cloning.
888
    def _synchronize_history(self, destination, revision_id):
889
        """See Branch._synchronize_history()."""
890
        destination.generate_revision_history(self.last_revision())
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
891
0.289.1 by Jelmer Vernooij
No parent location for remote repos.
892
    def _get_parent_location(self):
893
        return None
894
0.200.499 by Jelmer Vernooij
Implement RemoteBranch.{get,set}_push_location.
895
    def get_push_location(self):
896
        return None
897
898
    def set_push_location(self, url):
899
        pass
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
900
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
901
    def _iter_tag_refs(self):
902
        """Iterate over the tag refs.
903
904
        :param refs: Refs dictionary (name -> git sha1)
905
        :return: iterator over (ref_name, tag_name, peeled_sha1, unpeeled_sha1)
906
        """
907
        refs = self.controldir.get_refs_container()
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
908
        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.
909
            try:
910
                tag_name = ref_to_tag_name(ref_name)
911
            except (ValueError, UnicodeDecodeError):
912
                continue
913
            peeled = refs.get_peeled(ref_name)
914
            if peeled is None:
915
                try:
916
                    peeled = refs.peel_sha(unpeeled).id
917
                except KeyError:
918
                    # Let's just hope it's a commit
919
                    peeled = unpeeled
6973.6.2 by Jelmer Vernooij
Fix more tests.
920
            if not isinstance(tag_name, text_type):
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
921
                raise TypeError(tag_name)
922
            yield (ref_name, tag_name, peeled, unpeeled)
923
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
924
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
925
def remote_refs_dict_to_container(refs_dict, symrefs_dict={}):
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
926
    base = {}
927
    peeled = {}
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
928
    for k, v in refs_dict.items():
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
929
        if is_peeled(k):
930
            peeled[k[:-3]] = v
931
        else:
932
            base[k] = v
933
            peeled[k] = v
6964.2.1 by Jelmer Vernooij
Initial work to support brz-git on python3.
934
    for name, target in symrefs_dict.items():
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
935
        base[name] = SYMREF + target
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
936
    ret = DictRefsContainer(base)
937
    ret._peeled = peeled
938
    return ret