/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to remote.py

MoveĀ _get_client.

Show diffs side-by-side

added added

removed removed

Lines of Context:
17
17
from bzrlib import (
18
18
    config,
19
19
    debug,
20
 
    tag,
21
20
    trace,
22
21
    ui,
23
22
    urlutils,
27
26
    InvalidRevisionId,
28
27
    NoSuchFile,
29
28
    NoSuchRevision,
 
29
    NotBranchError,
30
30
    NotLocalUrl,
 
31
    UninitializableFormat,
31
32
    )
32
33
from bzrlib.transport import (
33
34
    Transport,
40
41
 
41
42
from bzrlib.plugins.git.branch import (
42
43
    GitBranch,
 
44
    GitTags,
 
45
    )
 
46
from bzrlib.plugins.git.dir import (
 
47
    GitControlDirFormat,
 
48
    GitDir,
 
49
    GitLockableFiles,
 
50
    GitLock,
43
51
    )
44
52
from bzrlib.plugins.git.errors import (
45
53
    GitSmartRemoteNotSupported,
46
54
    NoSuchRef,
47
55
    )
48
 
from bzrlib.plugins.git.dir import (
49
 
    GitDir,
50
 
    )
51
56
from bzrlib.plugins.git.mapping import (
52
57
    mapping_registry,
53
58
    )
65
70
    )
66
71
from dulwich.pack import (
67
72
    Pack,
68
 
    ThinPackData,
 
73
    PackData,
69
74
    )
70
75
import os
71
76
import tempfile
97
102
    return (host, port, username, path)
98
103
 
99
104
 
 
105
def parse_git_error(url, message):
 
106
    """Parse a remote git server error and return a bzr exception.
 
107
 
 
108
    :param url: URL of the remote repository
 
109
    :param message: Message sent by the remote git server
 
110
    """
 
111
    message = str(message).strip()
 
112
    if message.startswith("Could not find Repository "):
 
113
        return NotBranchError(url, message)
 
114
    # Don't know, just return it to the user as-is
 
115
    return BzrError(message)
 
116
 
 
117
 
100
118
class GitSmartTransport(Transport):
101
119
 
102
120
    def __init__(self, url, _client=None):
118
136
        raise NotImplementedError(self._get_client)
119
137
 
120
138
    def _get_path(self):
121
 
        return self._path
122
 
 
123
 
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
124
 
        if progress is None:
125
 
            def progress(text):
126
 
                trace.info("git: %s" % text)
127
 
        client = self._get_client(thin_packs=False)
128
 
        try:
129
 
            return client.fetch_pack(self._get_path(), determine_wants,
130
 
                graph_walker, pack_data, progress)
131
 
        except GitProtocolError, e:
132
 
            raise BzrError(e)
133
 
 
134
 
    def send_pack(self, get_changed_refs, generate_pack_contents):
135
 
        client = self._get_client(thin_packs=False)
136
 
        try:
137
 
            return client.send_pack(self._get_path(), get_changed_refs,
138
 
                generate_pack_contents)
139
 
        except GitProtocolError, e:
140
 
            raise BzrError(e)
 
139
        return urlutils.split_segment_parameters_raw(self._path)[0]
141
140
 
142
141
    def get(self, path):
143
142
        raise NoSuchFile(path)
173
172
    _scheme = 'git+ssh'
174
173
 
175
174
    def _get_path(self):
176
 
        if self._path.startswith("/~/"):
177
 
            return self._path[3:]
178
 
        return self._path
 
175
        path = urlutils.split_segment_parameters_raw(self._path)[0]
 
176
        if path.startswith("/~/"):
 
177
            return path[3:]
 
178
        return path
179
179
 
180
180
    def _get_client(self, thin_packs):
181
181
        if self._client is not None:
197
197
 
198
198
class RemoteGitDir(GitDir):
199
199
 
200
 
    def __init__(self, transport, lockfiles, format):
 
200
    def __init__(self, transport, lockfiles, format, get_client):
201
201
        self._format = format
202
202
        self.root_transport = transport
203
203
        self.transport = transport
204
204
        self._lockfiles = lockfiles
205
205
        self._mode_check_done = None
206
 
 
207
 
    def _branch_name_to_ref(self, name, default=None):
208
 
        return branch_name_to_ref(name, default=default)
 
206
        self._get_client = get_client
 
207
 
 
208
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
 
209
        if progress is None:
 
210
            def progress(text):
 
211
                trace.info("git: %s" % text)
 
212
        client = self._get_client(thin_packs=False)
 
213
        try:
 
214
            return client.fetch_pack(self.transport._get_path(), determine_wants,
 
215
                graph_walker, pack_data, progress)
 
216
        except GitProtocolError, e:
 
217
            raise parse_git_error(self.transport.external_url(), e)
 
218
 
 
219
    def send_pack(self, get_changed_refs, generate_pack_contents):
 
220
        client = self._get_client(thin_packs=False)
 
221
        try:
 
222
            return client.send_pack(self.transport._get_path(), get_changed_refs,
 
223
                generate_pack_contents)
 
224
        except GitProtocolError, e:
 
225
            raise parse_git_error(self.transport.external_url(), e)
 
226
 
 
227
    @property
 
228
    def user_url(self):
 
229
        return self.control_url
 
230
 
 
231
    @property
 
232
    def user_transport(self):
 
233
        return self.root_transport
209
234
 
210
235
    def open_repository(self):
211
236
        return RemoteGitRepository(self, self._lockfiles)
212
237
 
213
 
    def _open_branch(self, name=None, ignore_fallbacks=False, 
214
 
                    unsupported=False):
 
238
    def open_branch(self, name=None, unsupported=False,
 
239
            ignore_fallbacks=False):
215
240
        repo = self.open_repository()
216
 
        refname = self._branch_name_to_ref(name)
 
241
        refname = self._get_selected_ref(name)
217
242
        return RemoteGitBranch(self, repo, refname, self._lockfiles)
218
243
 
219
244
    def open_workingtree(self, recommend_upgrade=False):
235
260
    @property
236
261
    def data(self):
237
262
        if self._data is None:
238
 
            self._data = ThinPackData(self.resolve_ext_ref, self._data_path)
 
263
            self._data = PackData(self._data_path)
239
264
        return self._data
240
265
 
241
266
    @property
262
287
            os.remove(self._data_path)
263
288
 
264
289
 
 
290
class RemoteGitControlDirFormat(GitControlDirFormat):
 
291
    """The .git directory control format."""
 
292
 
 
293
    supports_workingtrees = False
 
294
 
 
295
    @classmethod
 
296
    def _known_formats(self):
 
297
        return set([RemoteGitControlDirFormat()])
 
298
 
 
299
    def open(self, transport, _found=None):
 
300
        """Open this directory.
 
301
 
 
302
        """
 
303
        # we dont grok readonly - git isn't integrated with transport.
 
304
        url = transport.base
 
305
        if url.startswith('readonly+'):
 
306
            url = url[len('readonly+'):]
 
307
        if (not url.startswith("git://") and not url.startswith("git+")):
 
308
            raise NotBranchError(transport.base)
 
309
        if not isinstance(transport, GitSmartTransport):
 
310
            raise NotBranchError(transport.base)
 
311
        lockfiles = GitLockableFiles(transport, GitLock())
 
312
        return RemoteGitDir(transport, lockfiles, self, transport._get_client)
 
313
 
 
314
    def get_format_description(self):
 
315
        return "Remote Git Repository"
 
316
 
 
317
    def initialize_on_transport(self, transport):
 
318
        raise UninitializableFormat(self)
 
319
 
 
320
 
265
321
class RemoteGitRepository(GitRepository):
266
322
 
267
323
    def __init__(self, gitdir, lockfiles):
269
325
        self._refs = None
270
326
 
271
327
    @property
272
 
    def inventories(self):
273
 
        raise GitSmartRemoteNotSupported()
274
 
 
275
 
    @property
276
 
    def revisions(self):
277
 
        raise GitSmartRemoteNotSupported()
278
 
 
279
 
    @property
280
 
    def texts(self):
 
328
    def user_url(self):
 
329
        return self.control_url
 
330
 
 
331
    def get_parent_map(self, revids):
281
332
        raise GitSmartRemoteNotSupported()
282
333
 
283
334
    def get_refs(self):
284
335
        if self._refs is not None:
285
336
            return self._refs
286
 
        self._refs = self.bzrdir.root_transport.fetch_pack(lambda x: [], None,
 
337
        self._refs = self.bzrdir.fetch_pack(lambda x: [], None,
287
338
            lambda x: None, lambda x: trace.mutter("git: %s" % x))
288
339
        return self._refs
289
340
 
290
341
    def fetch_pack(self, determine_wants, graph_walker, pack_data,
291
342
                   progress=None):
292
 
        return self._transport.fetch_pack(determine_wants, graph_walker,
 
343
        return self.bzrdir.fetch_pack(determine_wants, graph_walker,
293
344
                                          pack_data, progress)
294
345
 
295
346
    def send_pack(self, get_changed_refs, generate_pack_contents):
296
 
        return self._transport.send_pack(get_changed_refs, generate_pack_contents)
 
347
        return self.bzrdir.send_pack(get_changed_refs, generate_pack_contents)
297
348
 
298
349
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref,
299
350
                      progress=None):
300
351
        fd, path = tempfile.mkstemp(suffix=".pack")
301
 
        self.fetch_pack(determine_wants, graph_walker,
302
 
            lambda x: os.write(fd, x), progress)
303
 
        os.close(fd)
 
352
        try:
 
353
            self.fetch_pack(determine_wants, graph_walker,
 
354
                lambda x: os.write(fd, x), progress)
 
355
        finally:
 
356
            os.close(fd)
304
357
        if os.path.getsize(path) == 0:
305
358
            return EmptyObjectStoreIterator()
306
359
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
322
375
        return mapping.revision_id_foreign_to_bzr(foreign_revid)
323
376
 
324
377
 
325
 
class RemoteGitTagDict(tag.BasicTags):
326
 
 
327
 
    def __init__(self, branch):
328
 
        self.branch = branch
329
 
        self.repository = branch.repository
330
 
 
331
 
    def get_tag_dict(self):
332
 
        tags = {}
333
 
        for k, v in extract_tags(self.repository.get_refs()).iteritems():
334
 
            tags[k] = self.branch.mapping.revision_id_foreign_to_bzr(v)
335
 
        return tags
 
378
class RemoteGitTagDict(GitTags):
 
379
 
 
380
    def get_refs(self):
 
381
        return self.repository.get_refs()
 
382
 
 
383
    def _iter_tag_refs(self, refs):
 
384
        for k, (peeled, unpeeled) in extract_tags(refs).iteritems():
 
385
            yield (k, peeled, unpeeled,
 
386
                  self.branch.mapping.revision_id_foreign_to_bzr(peeled))
336
387
 
337
388
    def set_tag(self, name, revid):
338
389
        # FIXME: Not supported yet, should do a push of a new ref
346
397
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name,
347
398
                lockfiles)
348
399
 
 
400
    def last_revision_info(self):
 
401
        raise GitSmartRemoteNotSupported()
 
402
 
 
403
    @property
 
404
    def user_url(self):
 
405
        return self.control_url
 
406
 
 
407
    @property
 
408
    def control_url(self):
 
409
        return self.base
 
410
 
349
411
    def revision_history(self):
350
412
        raise GitSmartRemoteNotSupported()
351
413
 
365
427
        if self._sha is not None:
366
428
            return self._sha
367
429
        heads = self.repository.get_refs()
368
 
        name = self.bzrdir._branch_name_to_ref(self.name, "HEAD")
 
430
        name = branch_name_to_ref(self.name, "HEAD")
369
431
        if name in heads:
370
432
            self._sha = heads[name]
371
433
        else: