/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
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
21
from ... import (
0.200.596 by Jelmer Vernooij
Import RemoteGitBranch._get_config().
22
    config,
0.200.707 by Jelmer Vernooij
Add debug routines.
23
    debug,
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
24
    trace,
0.200.333 by Jelmer Vernooij
Support progress reporting when creating index.
25
    ui,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
26
    urlutils,
27
    )
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
28
from ...push import (
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
29
    PushResult,
30
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
31
from ...errors import (
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
32
    AlreadyBranchError,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
33
    BzrError,
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
34
    InProcessTransport,
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
35
    InvalidRevisionId,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
36
    NoSuchFile,
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
37
    NoSuchRevision,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
38
    NoSuchTag,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
39
    NotBranchError,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
40
    NotLocalUrl,
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
41
    NoWorkingTree,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
42
    UninitializableFormat,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
43
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
44
from ...transport import (
0.200.292 by Jelmer Vernooij
Fix formatting.
45
    Transport,
46
    )
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
47
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
48
from . import (
0.200.292 by Jelmer Vernooij
Fix formatting.
49
    lazy_check_versions,
50
    )
0.200.200 by Jelmer Vernooij
Register lazily where possible.
51
lazy_check_versions()
52
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
53
from .branch import (
0.200.292 by Jelmer Vernooij
Fix formatting.
54
    GitBranch,
0.295.1 by Jelmer Vernooij
Split up branch formats.
55
    GitBranchFormat,
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
56
    GitBranchPushResult,
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
57
    GitTags,
0.200.292 by Jelmer Vernooij
Fix formatting.
58
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
59
from .dir import (
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
60
    GitControlDirFormat,
61
    GitDir,
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
62
    BareLocalGitControlDirFormat,
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
63
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
64
from .errors import (
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
65
    GitSmartRemoteNotSupported,
0.200.292 by Jelmer Vernooij
Fix formatting.
66
    NoSuchRef,
67
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
68
from .mapping import (
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
69
    mapping_registry,
70
    )
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
71
from .object_store import (
72
    get_object_store,
73
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
74
from .repository import (
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
75
    GitRepository,
76
    )
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
77
from .refs import (
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
78
    branch_name_to_ref,
0.200.1487 by Jelmer Vernooij
Use peeling.
79
    is_peeled,
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
80
    ref_to_tag_name,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
81
    tag_name_to_ref,
0.200.872 by Jelmer Vernooij
Move refs code to separate module.
82
    )
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
83
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
84
import dulwich
85
import dulwich.client
0.200.292 by Jelmer Vernooij
Fix formatting.
86
from dulwich.errors import (
87
    GitProtocolError,
88
    )
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
89
from dulwich.pack import (
90
    Pack,
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
91
    pack_objects_to_data,
0.200.289 by Jelmer Vernooij
Cope with new member variables in RepositoryFormat.
92
    )
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
93
from dulwich.protocol import ZERO_SHA
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
94
from dulwich.refs import SYMREF
0.200.1487 by Jelmer Vernooij
Use peeling.
95
from dulwich.repo import DictRefsContainer
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
96
import os
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
97
import select
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
98
import tempfile
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
99
import urllib
100
import urlparse
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
101
102
# urlparse only supports a limited number of schemes by default
103
0.200.741 by Jelmer Vernooij
Cope with older versions of Python by adding git and git+ssh to the list of known schemes.
104
urlparse.uses_netloc.extend(['git', 'git+ssh'])
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
105
0.200.586 by Jelmer Vernooij
Fix issues pointed out by pyflakes.
106
from dulwich.pack import load_pack_index
0.200.306 by Jelmer Vernooij
Fix tests, split up InterGitNonGitRepository.
107
0.200.143 by Jelmer Vernooij
Reoncile InterGitRepository objects.
108
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
109
# Don't run any tests on GitSmartTransport as it is not intended to be
0.200.181 by Jelmer Vernooij
Support setting tags.
110
# a full implementation of Transport
111
def get_test_permutations():
112
    return []
113
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
114
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
115
def split_git_url(url):
0.200.709 by Jelmer Vernooij
When unpacking URLs, strip leftmost slash to match gits behaviour.
116
    """Split a Git URL.
117
118
    :param url: Git URL
119
    :return: Tuple with host, port, username, path.
120
    """
0.200.743 by Jelmer Vernooij
Fix URL parsing.
121
    (scheme, netloc, loc, _, _) = urlparse.urlsplit(url)
122
    path = urllib.unquote(loc)
0.246.2 by Jelmer Vernooij
Improve the fix dealing with git repo's in home directories.
123
    if path.startswith("/~"):
0.200.709 by Jelmer Vernooij
When unpacking URLs, strip leftmost slash to match gits behaviour.
124
        path = path[1:]
0.200.743 by Jelmer Vernooij
Fix URL parsing.
125
    (username, hostport) = urllib.splituser(netloc)
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
126
    (host, port) = urllib.splitnport(hostport, None)
127
    return (host, port, username, path)
128
129
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
130
class RemoteGitError(BzrError):
131
0.290.1 by Jelmer Vernooij
Avoid 'message' argument in RemoteGitError; apparently it breaks some versions of Python.
132
    _fmt = "Remote server error: %(msg)s"
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
133
134
0.200.1275 by Jelmer Vernooij
recognize missing repositories
135
def parse_git_error(url, message):
136
    """Parse a remote git server error and return a bzr exception.
137
138
    :param url: URL of the remote repository
139
    :param message: Message sent by the remote git server
140
    """
141
    message = str(message).strip()
142
    if message.startswith("Could not find Repository "):
143
        return NotBranchError(url, message)
0.200.1563 by Jelmer Vernooij
Improve error message.
144
    if message == "HEAD failed to update":
145
        base_url, _ = urlutils.split_segment_parameters(url)
146
        raise BzrError(
147
            ("Unable to update remote HEAD branch. To update the master "
148
             "branch, specify the URL %s,branch=master.") % base_url)
0.200.1275 by Jelmer Vernooij
recognize missing repositories
149
    # Don't know, just return it to the user as-is
0.200.1562 by Jelmer Vernooij
Add separate exception for remote errors.
150
    return RemoteGitError(message)
0.200.1275 by Jelmer Vernooij
recognize missing repositories
151
152
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
153
class GitSmartTransport(Transport):
154
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
155
    def __init__(self, url, _client=None):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
156
        Transport.__init__(self, url)
0.200.708 by Jelmer Vernooij
Factor out URL parsing.
157
        (self._host, self._port, self._username, self._path) = \
158
            split_git_url(url)
0.200.707 by Jelmer Vernooij
Add debug routines.
159
        if 'transport' in debug.debug_flags:
160
            trace.mutter('host: %r, user: %r, port: %r, path: %r',
161
                         self._host, self._username, self._port, self._path)
0.200.166 by Jelmer Vernooij
don't reuse client objects.
162
        self._client = _client
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
163
        self._stripped_path = self._path.rsplit(",", 1)[0]
0.200.166 by Jelmer Vernooij
don't reuse client objects.
164
0.200.543 by Jelmer Vernooij
Implement GitSmartTransport.external_url().
165
    def external_url(self):
166
        return self.base
167
0.200.238 by Jelmer Vernooij
Import Transport.has().
168
    def has(self, relpath):
169
        return False
170
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
171
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
172
        raise NotImplementedError(self._get_client)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
173
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
174
    def _get_path(self):
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
175
        return self._stripped_path
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
176
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
177
    def get(self, path):
178
        raise NoSuchFile(path)
179
0.200.160 by Jelmer Vernooij
Implement abspath.
180
    def abspath(self, relpath):
181
        return urlutils.join(self.base, relpath)
182
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
183
    def clone(self, offset=None):
184
        """See Transport.clone()."""
185
        if offset is None:
186
            newurl = self.base
187
        else:
188
            newurl = urlutils.join(self.base, offset)
189
0.200.307 by Jelmer Vernooij
Support git+ssh.
190
        return self.__class__(newurl, self._client)
191
192
193
class TCPGitSmartTransport(GitSmartTransport):
194
0.200.332 by Jelmer Vernooij
Support activity reporting.
195
    _scheme = 'git'
196
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
197
    def _get_client(self):
0.200.307 by Jelmer Vernooij
Support git+ssh.
198
        if self._client is not None:
199
            ret = self._client
200
            self._client = None
201
            return ret
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
202
        if self._host == '':
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
203
            # return dulwich.client.LocalGitClient()
204
            return dulwich.client.SubprocessGitClient()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
205
        return dulwich.client.TCPGitClient(self._host, self._port,
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
206
            report_activity=self._report_activity)
0.200.307 by Jelmer Vernooij
Support git+ssh.
207
208
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
209
class SSHSocketWrapper(object):
210
211
    def __init__(self, sock):
212
        self.sock = sock
213
214
    def read(self, len=None):
215
        return self.sock.recv(len)
216
217
    def write(self, data):
218
        return self.sock.write(data)
219
220
    def can_read(self):
221
        return len(select.select([self.sock.fileno()], [], [], 0)[0]) > 0
222
223
224
class DulwichSSHVendor(dulwich.client.SSHVendor):
225
226
    def __init__(self):
0.200.1641 by Jelmer Vernooij
Use relative imports where possible.
227
        from ...transport import ssh
0.200.1624 by Jelmer Vernooij
Add ssh vendor for dulwich that uses the bzr ssh vendor.
228
        self.bzr_ssh_vendor = ssh._get_ssh_vendor()
229
230
    def run_command(self, host, command, username=None, port=None):
231
        connection = self.bzr_ssh_vendor.connect_ssh(username=username,
232
            password=None, port=port, host=host, command=command)
233
        (kind, io_object) = connection.get_sock_or_pipes()
234
        if kind == 'socket':
235
            return SSHSocketWrapper(io_object)
236
        else:
237
            raise AssertionError("Unknown io object kind %r'" % kind)
238
239
240
#dulwich.client.get_ssh_vendor = DulwichSSHVendor
241
242
0.200.307 by Jelmer Vernooij
Support git+ssh.
243
class SSHGitSmartTransport(GitSmartTransport):
244
0.200.332 by Jelmer Vernooij
Support activity reporting.
245
    _scheme = 'git+ssh'
246
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
247
    def _get_path(self):
0.200.1464 by Jelmer Vernooij
Warn about ignoring path segment parameters when using bzr 2.4.
248
        path = self._stripped_path
0.200.1318 by Jelmer Vernooij
Strip segment parameters where necessary.
249
        if path.startswith("/~/"):
250
            return path[3:]
251
        return path
0.200.470 by Jelmer Vernooij
Properly parse username in URLs.
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.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
258
        location_config = config.LocationConfig(self.base)
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
259
        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.
260
            report_activity=self._report_activity)
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
261
        # Set up alternate pack program paths
262
        upload_pack = location_config.get_user_option('git_upload_pack')
263
        if upload_pack:
0.200.949 by Jelmer Vernooij
merge support for specifying alternative paths for git executables.
264
            client.alternative_paths["upload-pack"] = upload_pack
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
265
        receive_pack = location_config.get_user_option('git_receive_pack')
266
        if receive_pack:
0.200.949 by Jelmer Vernooij
merge support for specifying alternative paths for git executables.
267
            client.alternative_paths["receive-pack"] = receive_pack
0.253.1 by Ross Light
Added configuration options for git-upload-pack and git-receive-pack
268
        return client
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
269
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
270
0.295.1 by Jelmer Vernooij
Split up branch formats.
271
class RemoteGitBranchFormat(GitBranchFormat):
272
273
    def get_format_description(self):
274
        return 'Remote Git Branch'
275
276
    @property
277
    def _matchingcontroldir(self):
278
        return RemoteGitControlDirFormat()
279
0.295.2 by Jelmer Vernooij
Make RemoteGitBranchFormat uninitializeable.
280
    def initialize(self, a_controldir, name=None, repository=None,
281
                   append_revisions_only=None):
282
        raise UninitializableFormat(self)
283
0.295.1 by Jelmer Vernooij
Split up branch formats.
284
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
285
def default_report_progress(text):
286
    if text.startswith('error: '):
287
        trace.show_error('git: %s', text[len('error: '):])
288
    else:
289
        trace.mutter("git: %s" % text)
290
291
0.200.148 by Jelmer Vernooij
Share more infrastructure between LocalGitDir and RemoteGitDir.
292
class RemoteGitDir(GitDir):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
293
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
294
    def __init__(self, transport, format, client, client_path):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
295
        self._format = format
296
        self.root_transport = transport
297
        self.transport = transport
0.200.381 by Jelmer Vernooij
Support working trees properly, status and ls.
298
        self._mode_check_done = None
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
299
        self._client = client
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
300
        self._client_path = client_path
0.200.1396 by Jelmer Vernooij
Support updating tags in remote branches during pull.
301
        self.base = self.root_transport.base
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
302
        self._refs = None
0.200.1335 by Jelmer Vernooij
Move _get_client.
303
0.322.1 by Jelmer Vernooij
Fix access of remote git branches.
304
    @property
305
    def _gitrepository_class(self):
306
        return RemoteGitRepository
307
0.200.1335 by Jelmer Vernooij
Move _get_client.
308
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
309
        if progress is None:
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
310
            progress = default_report_progress
0.200.1335 by Jelmer Vernooij
Move _get_client.
311
        try:
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
312
            result = self._client.fetch_pack(self._client_path, determine_wants,
0.200.1335 by Jelmer Vernooij
Move _get_client.
313
                graph_walker, pack_data, progress)
0.376.1 by Jelmer Vernooij
Add tests for remote operations.
314
            if result.refs is None:
315
                result.refs = {}
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
316
            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.
317
            return result
0.200.1335 by Jelmer Vernooij
Move _get_client.
318
        except GitProtocolError, e:
319
            raise parse_git_error(self.transport.external_url(), e)
320
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
321
    def send_pack(self, get_changed_refs, generate_pack_data, progress=None):
322
        if progress is None:
323
            progress = default_report_progress
324
0.200.1335 by Jelmer Vernooij
Move _get_client.
325
        try:
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
326
            return self._client.send_pack(self._client_path, get_changed_refs,
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
327
                generate_pack_data, progress)
0.200.1335 by Jelmer Vernooij
Move _get_client.
328
        except GitProtocolError, e:
329
            raise parse_git_error(self.transport.external_url(), e)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
330
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
331
    def create_branch(self, name=None, repository=None,
332
                      append_revisions_only=None, ref=None):
333
        refname = self._get_selected_ref(name, ref)
334
        if refname != b'HEAD' and refname in self.get_refs_container():
335
            raise AlreadyBranchError(self.user_url)
336
        if refname in self.get_refs_container():
337
            ref_chain, unused_sha = self.get_refs_container().follow(self._get_selected_ref(None))
338
            if ref_chain[0] == b'HEAD':
339
                refname = ref_chain[1]
340
        repo = self.open_repository()
341
        return RemoteGitBranch(self, repo, refname)
342
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
343
    def destroy_branch(self, name=None):
344
        refname = self._get_selected_ref(name)
345
        def get_changed_refs(old_refs):
346
            ret = dict(old_refs)
347
            if not refname in ret:
0.200.1395 by Jelmer Vernooij
Fix error reporting.
348
                raise NotBranchError(self.user_url)
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
349
            ret[refname] = dulwich.client.ZERO_SHA
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
350
            return ret
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
351
        def generate_pack_data(have, want, ofs_delta=False):
352
            return pack_objects_to_data([])
353
        self.send_pack(get_changed_refs, generate_pack_data)
0.200.1393 by Jelmer Vernooij
Implement removal of remote branches.
354
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
355
    @property
356
    def user_url(self):
357
        return self.control_url
358
0.200.1314 by Jelmer Vernooij
Provide RemoteGitDir.user_transport.
359
    @property
360
    def user_transport(self):
361
        return self.root_transport
362
0.200.1395 by Jelmer Vernooij
Fix error reporting.
363
    @property
364
    def control_url(self):
365
        return self.control_transport.base
366
367
    @property
368
    def control_transport(self):
369
        return self.root_transport
370
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
371
    def open_repository(self):
0.200.1415 by Jelmer Vernooij
Fix lock files for remote directories.
372
        return RemoteGitRepository(self)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
373
0.200.1310 by Jelmer Vernooij
Add _get_selected_ref method.
374
    def open_branch(self, name=None, unsupported=False,
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
375
            ignore_fallbacks=False, ref=None, possible_transports=None,
376
            nascent_ok=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
377
        repo = self.open_repository()
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
378
        ref = self._get_selected_ref(name, ref)
379
        if not nascent_ok and ref not in self.get_refs_container():
380
            raise NotBranchError(self.root_transport.base,
381
                    controldir=self)
382
        ref_chain, unused_sha = self.get_refs_container().follow(ref)
383
        return RemoteGitBranch(self, repo, ref_chain[-1])
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
384
0.200.662 by Jelmer Vernooij
Deal with recommend_upgrade argument to open_workingtree.
385
    def open_workingtree(self, recommend_upgrade=False):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
386
        raise NotLocalUrl(self.transport.base)
387
0.310.4 by Jelmer Vernooij
Implement RemoteControlDir.has_workingtree.
388
    def has_workingtree(self):
389
        return False
390
0.200.1489 by Jelmer Vernooij
More fixes to peel handling.
391
    def get_peeled(self, name):
392
        return self.get_refs_container().get_peeled(name)
393
0.200.1487 by Jelmer Vernooij
Use peeling.
394
    def get_refs_container(self):
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
395
        if self._refs is not None:
396
            return self._refs
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
397
        result = self.fetch_pack(lambda x: None, None,
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
398
            lambda x: None, lambda x: trace.mutter("git: %s" % x))
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
399
        self._refs = remote_refs_dict_to_container(
400
                result.refs, result.symrefs)
0.200.1434 by Jelmer Vernooij
Move refs access to control dir.
401
        return self._refs
402
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
403
    def push_branch(self, source, revision_id=None, overwrite=False,
404
                    remember=False, create_prefix=False, lossy=False,
405
                    name=None):
406
        """Push the source branch into this ControlDir."""
407
        if revision_id is None:
408
            # No revision supplied by the user, default to the branch
409
            # revision
410
            revision_id = source.last_revision()
411
412
        push_result = PushResult()
413
        push_result.workingtree_updated = None
414
        push_result.master_branch = None
415
        push_result.source_branch = source
416
        push_result.stacked_on = None
417
        push_result.branch_push_result = None
418
        repo = self.find_repository()
419
        refname = self._get_selected_ref(name)
420
        source_store = get_object_store(source.repository)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
421
        with source_store.lock_read():
422
            def get_changed_refs(refs):
423
                self._refs = remote_refs_dict_to_container(refs)
424
                ret = dict(refs)
425
                # TODO(jelmer): Unpeel if necessary
426
                if lossy:
427
                    ret[refname] = source_store._lookup_revision_sha1(revision_id)
428
                else:
429
                    ret[refname] = repo.lookup_bzr_revision_id(revision_id)[0]
430
                return ret
431
            if lossy:
432
                generate_pack_data = source_store.generate_lossy_pack_data
433
            else:
434
                generate_pack_data = source_store.generate_pack_data
435
            new_refs = self.send_pack(get_changed_refs, generate_pack_data)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
436
        push_result.new_revid = repo.lookup_foreign_revision_id(
437
                new_refs[refname])
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
438
        try:
439
            old_remote = self._refs[refname]
440
        except KeyError:
441
            old_remote = ZERO_SHA
442
        push_result.old_revid = repo.lookup_foreign_revision_id(old_remote)
443
        self._refs = remote_refs_dict_to_container(new_refs)
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
444
        push_result.old_revno = None
445
        push_result.target_branch = self.open_branch(name)
0.403.3 by Jelmer Vernooij
Test RemoteGitDir.push_branch.
446
        if old_remote != ZERO_SHA:
447
            push_result.branch_push_result = GitBranchPushResult()
448
            push_result.branch_push_result.source_branch = source
449
            push_result.branch_push_result.target_branch = push_result.target_branch
450
            push_result.branch_push_result.local_branch = None
451
            push_result.branch_push_result.master_branch = push_result.target_branch
452
            push_result.branch_push_result.old_revid = push_result.old_revid
453
            push_result.branch_push_result.new_revid = push_result.new_revid
0.401.4 by Jelmer Vernooij
Implement RemoteGitDir.push_branch.
454
        if source.get_push_location() is None or remember:
455
            source.set_push_location(push_result.target_branch.base)
456
        return push_result
457
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
458
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
459
class EmptyObjectStoreIterator(dict):
460
461
    def iterobjects(self):
462
        return []
463
464
0.200.218 by Jelmer Vernooij
Simplify TemporaryPack implementation.
465
class TemporaryPackIterator(Pack):
466
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
467
    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.
468
        super(TemporaryPackIterator, self).__init__(
469
            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.
470
        self._idx_load = lambda: self._idx_load_or_generate(self._idx_path)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
471
0.278.2 by William Grant
Also override _idx_load rather than index, to be a bit cleaner.
472
    def _idx_load_or_generate(self, path):
473
        if not os.path.exists(path):
474
            pb = ui.ui_factory.nested_progress_bar()
475
            try:
476
                def report_progress(cur, total):
477
                    pb.update("generating index", cur, total)
478
                self.data.create_index(path,
479
                    progress=report_progress)
480
            finally:
481
                pb.finished()
482
        return load_pack_index(path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
483
484
    def __del__(self):
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
485
        if self._idx is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
486
            self._idx.close()
487
            os.remove(self._idx_path)
0.200.611 by Jelmer Vernooij
Merge warning fix from Naoki.
488
        if self._data is not None:
0.241.1 by Naoki INADA
Fix can't delete tempfile on Windows
489
            self._data.close()
490
            os.remove(self._data_path)
0.200.205 by Jelmer Vernooij
Fix remote fetching.
491
492
0.200.1337 by Jelmer Vernooij
Re-use http connection if possible.
493
class BzrGitHttpClient(dulwich.client.HttpGitClient):
494
495
    def __init__(self, transport, *args, **kwargs):
496
        self.transport = transport
497
        super(BzrGitHttpClient, self).__init__(transport.external_url(), *args, **kwargs)
498
        import urllib2
499
        self._http_perform = getattr(self.transport, "_perform", urllib2.urlopen)
500
501
    def _perform(self, req):
502
        req.accepted_errors = (200, 404)
503
        req.follow_redirections = True
504
        req.redirected_to = None
505
        return self._http_perform(req)
506
507
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
508
class RemoteGitControlDirFormat(GitControlDirFormat):
509
    """The .git directory control format."""
510
511
    supports_workingtrees = False
512
513
    @classmethod
514
    def _known_formats(self):
515
        return set([RemoteGitControlDirFormat()])
516
0.295.1 by Jelmer Vernooij
Split up branch formats.
517
    def get_branch_format(self):
518
        return RemoteGitBranchFormat()
519
0.200.1413 by Jelmer Vernooij
Fix is_initializable()
520
    def is_initializable(self):
521
        return False
522
523
    def is_supported(self):
524
        return True
525
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
526
    def open(self, transport, _found=None):
527
        """Open this directory.
528
529
        """
530
        # we dont grok readonly - git isn't integrated with transport.
531
        url = transport.base
532
        if url.startswith('readonly+'):
533
            url = url[len('readonly+'):]
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
534
        scheme = urlparse.urlsplit(transport.external_url())[0]
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
535
        if isinstance(transport, GitSmartTransport):
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
536
            client = transport._get_client()
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
537
            client_path = transport._get_path()
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
538
        elif scheme in ("http", "https"):
539
            client = BzrGitHttpClient(transport)
0.200.1555 by Jelmer Vernooij
Remove segment parameters for http smart transports.
540
            client_path, _ = urlutils.split_segment_parameters(transport._path)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
541
        elif scheme == 'file':
542
            client = dulwich.client.LocalGitClient()
543
            client_path = transport.local_abspath('.')
0.200.1336 by Jelmer Vernooij
Support the git smart server http protocol.
544
        else:
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
545
            raise NotBranchError(transport.base)
0.344.1 by Jelmer Vernooij
Allow using local git executable by accessing git:///some/path.
546
        if not _found:
547
            pass # TODO(jelmer): Actually probe for something
548
        return RemoteGitDir(transport, self, client, client_path)
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
549
550
    def get_format_description(self):
551
        return "Remote Git Repository"
552
553
    def initialize_on_transport(self, transport):
554
        raise UninitializableFormat(self)
555
0.200.1412 by Jelmer Vernooij
Implement GitControlDirFormat.supports_transport.
556
    def supports_transport(self, transport):
557
        try:
558
            external_url = transport.external_url()
559
        except InProcessTransport:
560
            raise NotBranchError(path=transport.base)
561
        return (external_url.startswith("http:") or
562
                external_url.startswith("https:") or
563
                external_url.startswith("git+") or
564
                external_url.startswith("git:"))
565
0.200.1137 by Jelmer Vernooij
Support BzrProber.known_formats().
566
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
567
class RemoteGitRepository(GitRepository):
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
568
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
569
    @property
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
570
    def user_url(self):
571
        return self.control_url
572
0.200.1288 by Jelmer Vernooij
Properly raise GitRemoteNotSupported from RemoteGitRepository.
573
    def get_parent_map(self, revids):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
574
        raise GitSmartRemoteNotSupported(self.get_parent_map, self)
0.200.319 by Jelmer Vernooij
Print proper error when trying unsupported operations against a git server.
575
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
576
    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.
577
                   progress=None):
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
578
        return self.controldir.fetch_pack(determine_wants, graph_walker,
0.200.456 by Jelmer Vernooij
Fix git -> git fetching.
579
                                          pack_data, progress)
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
580
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
581
    def send_pack(self, get_changed_refs, generate_pack_data):
582
        return self.controldir.send_pack(get_changed_refs, generate_pack_data)
0.200.427 by Jelmer Vernooij
make send_pack accessible.
583
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
584
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
585
                      progress=None):
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
586
        fd, path = tempfile.mkstemp(suffix=".pack")
0.200.1299 by Jelmer Vernooij
Make sure file gets closed.
587
        try:
588
            self.fetch_pack(determine_wants, graph_walker,
589
                lambda x: os.write(fd, x), progress)
590
        finally:
591
            os.close(fd)
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
592
        if os.path.getsize(path) == 0:
0.225.2 by Jelmer Vernooij
Handle situation when repository is already up to date during pull.
593
            return EmptyObjectStoreIterator()
0.200.226 by Jelmer Vernooij
Merge thin-pack work.
594
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
0.200.167 by Jelmer Vernooij
Implement fetch_objects properly.
595
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
596
    def lookup_bzr_revision_id(self, bzr_revid, mapping=None):
0.200.415 by Jelmer Vernooij
make 'bzr pull --revision' work for remote repositories.
597
        # This won't work for any round-tripped bzr revisions, but it's a start..
598
        try:
599
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
600
        except InvalidRevisionId:
601
            raise NoSuchRevision(self, bzr_revid)
602
0.252.48 by Jelmer Vernooij
Implement lookup_foreign_revision for remote branches.
603
    def lookup_foreign_revision_id(self, foreign_revid, mapping=None):
604
        """Lookup a revision id.
605
606
        """
607
        if mapping is None:
608
            mapping = self.get_mapping()
609
        # Not really an easy way to parse foreign revids here..
610
        return mapping.revision_id_foreign_to_bzr(foreign_revid)
611
0.200.1446 by Jelmer Vernooij
Add stub for RemoteGitRepository.revision_tree.
612
    def revision_tree(self, revid):
613
        raise GitSmartRemoteNotSupported(self.revision_tree, self)
614
0.200.1481 by Jelmer Vernooij
'Implement' RemoteGitRepository.get_revisions.
615
    def get_revisions(self, revids):
616
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
617
0.200.1557 by Jelmer Vernooij
Implement RemoteGitRepository.has_revisions.
618
    def has_revisions(self, revids):
619
        raise GitSmartRemoteNotSupported(self.get_revisions, self)
620
0.200.138 by Jelmer Vernooij
Add initial infrastructure for accessing remote git repositories.
621
0.200.1064 by Jelmer Vernooij
Use common base class for tags.
622
class RemoteGitTagDict(GitTags):
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
623
624
    def set_tag(self, name, revid):
0.377.1 by Jelmer Vernooij
Fix some remote operations and add more tests.
625
        sha = self.branch.lookup_bzr_revision_id(revid)[0]
626
        self._set_ref(name, sha)
627
628
    def delete_tag(self, name):
629
        self._set_ref(name, dulwich.client.ZERO_SHA)
630
631
    def _set_ref(self, name, sha):
632
        ref = tag_name_to_ref(name)
633
        def get_changed_refs(old_refs):
634
            ret = dict(old_refs)
635
            if sha == dulwich.client.ZERO_SHA and ref not in ret:
636
                raise NoSuchTag(name)
637
            ret[ref] = sha
638
            return ret
639
        def generate_pack_data(have, want, ofs_delta=False):
640
            return pack_objects_to_data([])
641
        self.repository.send_pack(get_changed_refs, generate_pack_data)
0.228.3 by Jelmer Vernooij
Fix tags when fetching from remotes.
642
643
0.200.139 by Jelmer Vernooij
Share more code between local and remote classes, support opening remote branches.
644
class RemoteGitBranch(GitBranch):
645
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
646
    def __init__(self, controldir, repository, name):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
647
        self._sha = None
0.295.1 by Jelmer Vernooij
Split up branch formats.
648
        super(RemoteGitBranch, self).__init__(controldir, repository, name,
649
                RemoteGitBranchFormat())
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
650
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
651
    def last_revision_info(self):
0.200.1398 by Jelmer Vernooij
Make GitSmartRemoteNotSupported derive from UnsupportedOperation.
652
        raise GitSmartRemoteNotSupported(self.last_revision_info, self)
0.200.1317 by Jelmer Vernooij
Avoid NotImplementedError.
653
0.200.1068 by Jelmer Vernooij
Implement user_url/control_url.
654
    @property
655
    def user_url(self):
656
        return self.control_url
657
658
    @property
659
    def control_url(self):
660
        return self.base
661
0.200.1436 by Jelmer Vernooij
Raise UnsupportedOperation for `Branch.revision_id_to_dotted_revno`,
662
    def revision_id_to_revno(self, revision_id):
663
        raise GitSmartRemoteNotSupported(self.revision_id_to_revno, self)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
664
665
    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.
666
        return self.lookup_foreign_revision_id(self.head)
0.200.461 by Jelmer Vernooij
Reduce number of round trips when fetching from Git.
667
668
    @property
669
    def head(self):
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
670
        if self._sha is not None:
671
            return self._sha
0.200.1648 by Jelmer Vernooij
Fix compatibility with newer versions of breezy.
672
        refs = self.controldir.get_refs_container()
0.200.1561 by Jelmer Vernooij
Some fixes for colocated branch handling.
673
        name = branch_name_to_ref(self.name)
0.200.1386 by Jelmer Vernooij
Friendlier message if HEAD is not found.
674
        try:
675
            self._sha = refs[name]
676
        except KeyError:
677
            raise NoSuchRef(name, self.repository.user_url, refs)
0.200.919 by Jelmer Vernooij
Simplify ref handling in remote.py.
678
        return self._sha
0.200.141 by Jelmer Vernooij
Separate out local and remote fetching.
679
0.200.169 by Jelmer Vernooij
Fix branch cloning.
680
    def _synchronize_history(self, destination, revision_id):
681
        """See Branch._synchronize_history()."""
682
        destination.generate_revision_history(self.last_revision())
0.200.695 by Jelmer Vernooij
Clean up trailing whitespace.
683
0.289.1 by Jelmer Vernooij
No parent location for remote repos.
684
    def _get_parent_location(self):
685
        return None
686
0.200.499 by Jelmer Vernooij
Implement RemoteBranch.{get,set}_push_location.
687
    def get_push_location(self):
688
        return None
689
690
    def set_push_location(self, url):
691
        pass
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
692
0.375.1 by Jelmer Vernooij
Fix remote tests, warn when fetching git->bzr and bzr->git.
693
    def _iter_tag_refs(self):
694
        """Iterate over the tag refs.
695
696
        :param refs: Refs dictionary (name -> git sha1)
697
        :return: iterator over (ref_name, tag_name, peeled_sha1, unpeeled_sha1)
698
        """
699
        refs = self.controldir.get_refs_container()
700
        for ref_name, unpeeled in refs.as_dict().iteritems():
701
            try:
702
                tag_name = ref_to_tag_name(ref_name)
703
            except (ValueError, UnicodeDecodeError):
704
                continue
705
            peeled = refs.get_peeled(ref_name)
706
            if peeled is None:
707
                try:
708
                    peeled = refs.peel_sha(unpeeled).id
709
                except KeyError:
710
                    # Let's just hope it's a commit
711
                    peeled = unpeeled
712
            if type(tag_name) is not unicode:
713
                raise TypeError(tag_name)
714
            yield (ref_name, tag_name, peeled, unpeeled)
715
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
716
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
717
def remote_refs_dict_to_container(refs_dict, symrefs_dict={}):
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
718
    base = {}
719
    peeled = {}
720
    for k, v in refs_dict.iteritems():
721
        if is_peeled(k):
722
            peeled[k[:-3]] = v
723
        else:
724
            base[k] = v
725
            peeled[k] = v
0.382.1 by Jelmer Vernooij
Various fixes for annotated tags and symrefs.
726
    for name, target in symrefs_dict.iteritems():
727
        base[name] = SYMREF + target
0.200.1488 by Jelmer Vernooij
Factor out remote_refs_dict_to_container.
728
    ret = DictRefsContainer(base)
729
    ret._peeled = peeled
730
    return ret