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