/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

Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2008 Canonical Ltd
 
1
# Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
16
 
17
17
import bzrlib
18
 
from bzrlib import urlutils
19
 
from bzrlib.bzrdir import BzrDir, BzrDirFormat
20
 
from bzrlib.errors import NoSuchFile, NotLocalUrl
21
 
from bzrlib.lockable_files import TransportLock
22
 
from bzrlib.repository import Repository
23
 
from bzrlib.trace import info
24
 
from bzrlib.transport import Transport
 
18
from bzrlib import (
 
19
    config,
 
20
    tag,
 
21
    trace,
 
22
    ui,
 
23
    urlutils,
 
24
    )
 
25
from bzrlib.errors import (
 
26
    BzrError,
 
27
    InvalidRevisionId,
 
28
    NoSuchFile,
 
29
    NoSuchRevision,
 
30
    NotLocalUrl,
 
31
    )
 
32
from bzrlib.trace import (
 
33
    info,
 
34
    )
 
35
from bzrlib.transport import (
 
36
    Transport,
 
37
    )
25
38
 
26
 
from bzrlib.plugins.git import lazy_check_versions
 
39
from bzrlib.plugins.git import (
 
40
    lazy_check_versions,
 
41
    )
27
42
lazy_check_versions()
28
43
 
29
 
from bzrlib.plugins.git.branch import GitBranch
30
 
from bzrlib.plugins.git.errors import NoSuchRef
31
 
from bzrlib.plugins.git.dir import GitDir
32
 
from bzrlib.plugins.git.foreign import ForeignBranch
33
 
from bzrlib.plugins.git.repository import GitFormat, GitRepository
 
44
from bzrlib.plugins.git.branch import (
 
45
    GitBranch,
 
46
    extract_tags,
 
47
    )
 
48
from bzrlib.plugins.git.errors import (
 
49
    GitSmartRemoteNotSupported,
 
50
    NoSuchRef,
 
51
    )
 
52
from bzrlib.plugins.git.dir import (
 
53
    GitDir,
 
54
    )
 
55
from bzrlib.plugins.git.mapping import (
 
56
    mapping_registry,
 
57
    )
 
58
from bzrlib.plugins.git.repository import (
 
59
    GitRepository,
 
60
    )
34
61
 
 
62
import dulwich as git
 
63
from dulwich.errors import (
 
64
    GitProtocolError,
 
65
    )
 
66
from dulwich.pack import (
 
67
    Pack,
 
68
    )
35
69
import os
36
70
import tempfile
37
71
import urllib
38
72
import urlparse
39
73
 
40
 
import dulwich as git
41
 
from dulwich.pack import PackData, Pack, PackIndex
 
74
from dulwich.pack import load_pack_index
 
75
 
42
76
 
43
77
# Don't run any tests on GitSmartTransport as it is not intended to be 
44
78
# a full implementation of Transport
51
85
    def __init__(self, url, _client=None):
52
86
        Transport.__init__(self, url)
53
87
        (scheme, _, loc, _, _) = urlparse.urlsplit(url)
54
 
        assert scheme == "git"
55
88
        hostport, self._path = urllib.splithost(loc)
56
 
        (self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
 
89
        (self._username, hostport) = urllib.splituser(hostport)
 
90
        (self._host, self._port) = urllib.splitnport(hostport, None)
57
91
        self._client = _client
58
92
 
59
 
    def _get_client(self):
60
 
        if self._client is not None:
61
 
            ret = self._client
62
 
            self._client = None
63
 
            return ret
64
 
        return git.client.TCPGitClient(self._host, self._port, 
65
 
            capabilities=["multi_ack", "side-band-64k", "ofs-delta", "side-band"])
 
93
    def external_url(self):
 
94
        return self.base
 
95
 
 
96
    def has(self, relpath):
 
97
        return False
 
98
 
 
99
    def _get_client(self, thin_packs):
 
100
        raise NotImplementedError(self._get_client)
 
101
 
 
102
    def _get_path(self):
 
103
        return self._path
66
104
 
67
105
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
68
106
        if progress is None:
69
107
            def progress(text):
70
108
                info("git: %s" % text)
71
 
        self._get_client().fetch_pack(self._path, determine_wants, 
72
 
            graph_walker, pack_data, progress)
 
109
        client = self._get_client(thin_packs=False)
 
110
        try:
 
111
            return client.fetch_pack(self._get_path(), determine_wants, 
 
112
                graph_walker, pack_data, progress)
 
113
        except GitProtocolError, e:
 
114
            raise BzrError(e)
 
115
 
 
116
    def send_pack(self, get_changed_refs, generate_pack_contents):
 
117
        client = self._get_client(thin_packs=False)
 
118
        try:
 
119
            return client.send_pack(self._get_path(), get_changed_refs, 
 
120
                generate_pack_contents)
 
121
        except GitProtocolError, e:
 
122
            raise BzrError(e)
73
123
 
74
124
    def get(self, path):
75
125
        raise NoSuchFile(path)
84
134
        else:
85
135
            newurl = urlutils.join(self.base, offset)
86
136
 
87
 
        return GitSmartTransport(newurl, self._client)
 
137
        return self.__class__(newurl, self._client)
 
138
 
 
139
 
 
140
class TCPGitSmartTransport(GitSmartTransport):
 
141
 
 
142
    _scheme = 'git'
 
143
 
 
144
    def _get_client(self, thin_packs):
 
145
        if self._client is not None:
 
146
            ret = self._client
 
147
            self._client = None
 
148
            return ret
 
149
        return git.client.TCPGitClient(self._host, self._port, thin_packs=thin_packs,
 
150
            report_activity=self._report_activity)
 
151
 
 
152
 
 
153
class SSHGitSmartTransport(GitSmartTransport):
 
154
 
 
155
    _scheme = 'git+ssh'
 
156
 
 
157
    def _get_path(self):
 
158
        if self._path.startswith("/~/"):
 
159
            return self._path[3:]
 
160
        return self._path
 
161
 
 
162
    def _get_client(self, thin_packs):
 
163
        if self._client is not None:
 
164
            ret = self._client
 
165
            self._client = None
 
166
            return ret
 
167
        return git.client.SSHGitClient(self._host, self._port, self._username,
 
168
            thin_packs=thin_packs, report_activity=self._report_activity)
88
169
 
89
170
 
90
171
class RemoteGitDir(GitDir):
94
175
        self.root_transport = transport
95
176
        self.transport = transport
96
177
        self._lockfiles = lockfiles
 
178
        self._mode_check_done = None
97
179
 
98
180
    def open_repository(self):
99
181
        return RemoteGitRepository(self, self._lockfiles)
100
182
 
101
 
    def open_branch(self, _unsupported=False):
 
183
    def open_branch(self, ignore_fallbacks=False):
102
184
        repo = self.open_repository()
103
185
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
104
186
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
116
198
class TemporaryPackIterator(Pack):
117
199
 
118
200
    def __init__(self, path, resolve_ext_ref):
 
201
        super(TemporaryPackIterator, self).__init__(path)
119
202
        self.resolve_ext_ref = resolve_ext_ref
120
 
        super(TemporaryPackIterator, self).__init__(path)
121
203
 
122
204
    @property
123
 
    def idx(self):
 
205
    def index(self):
124
206
        if self._idx is None:
125
 
            self._data.create_index_v2(self._idx_path, self.resolve_ext_ref)
126
 
            self._idx = PackIndex(self._idx_path)
 
207
            if not os.path.exists(self._idx_path):
 
208
                pb = ui.ui_factory.nested_progress_bar()
 
209
                try:
 
210
                    def report_progress(cur, total):
 
211
                        pb.update("generating index", cur, total)
 
212
                    self.data.create_index(self._idx_path, self.resolve_ext_ref,
 
213
                        progress=report_progress)
 
214
                finally:
 
215
                    pb.finished()
 
216
            self._idx = load_pack_index(self._idx_path)
127
217
        return self._idx
128
218
 
129
219
    def __del__(self):
135
225
 
136
226
    def __init__(self, gitdir, lockfiles):
137
227
        GitRepository.__init__(self, gitdir, lockfiles)
 
228
        self._refs = None
 
229
 
 
230
    @property
 
231
    def inventories(self):
 
232
        raise GitSmartRemoteNotSupported()
 
233
 
 
234
    @property
 
235
    def revisions(self):
 
236
        raise GitSmartRemoteNotSupported()
 
237
 
 
238
    @property
 
239
    def texts(self):
 
240
        raise GitSmartRemoteNotSupported()
 
241
 
 
242
    def get_refs(self):
 
243
        if self._refs is not None:
 
244
            return self._refs
 
245
        self._refs = self.bzrdir.root_transport.fetch_pack(lambda x: [], None, 
 
246
            lambda x: None, lambda x: trace.mutter("git: %s" % x))
 
247
        return self._refs
138
248
 
139
249
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
140
250
                   progress=None):
141
 
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
142
 
            progress)
 
251
        return self._transport.fetch_pack(determine_wants, graph_walker,
 
252
                                          pack_data, progress)
 
253
 
 
254
    def send_pack(self, get_changed_refs, generate_pack_contents):
 
255
        return self._transport.send_pack(get_changed_refs, generate_pack_contents)
143
256
 
144
257
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
145
258
        fd, path = tempfile.mkstemp(suffix=".pack")
149
262
            return EmptyObjectStoreIterator()
150
263
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
151
264
 
 
265
    def lookup_git_revid(self, bzr_revid):
 
266
        # This won't work for any round-tripped bzr revisions, but it's a start..
 
267
        try:
 
268
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
 
269
        except InvalidRevisionId:
 
270
            raise NoSuchRevision(self, bzr_revid)
 
271
 
 
272
 
 
273
class RemoteGitTagDict(tag.BasicTags):
 
274
 
 
275
    def __init__(self, branch):
 
276
        self.branch = branch
 
277
        self.repository = branch.repository
 
278
 
 
279
    def get_tag_dict(self):
 
280
        return extract_tags(self.repository.get_refs(), self.branch.mapping)
 
281
 
 
282
    def set_tag(self, name, revid):
 
283
        # FIXME: Not supported yet, should do a push of a new ref
 
284
        raise NotImplementedError(self.set_tag)
 
285
 
152
286
 
153
287
class RemoteGitBranch(GitBranch):
154
288
 
155
289
    def __init__(self, bzrdir, repository, name, lockfiles):
156
 
        def determine_wants(heads):
157
 
            if not name in heads:
158
 
                raise NoSuchRef(name)
159
 
            self._ref = heads[name]
160
 
        bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None, 
161
 
                             lambda x: mutter("git: %s" % x))
162
 
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
 
290
        self._ref = None
 
291
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, 
 
292
                lockfiles)
 
293
 
 
294
    def revision_history(self):
 
295
        raise GitSmartRemoteNotSupported()
163
296
 
164
297
    def last_revision(self):
165
 
        return self.mapping.revision_id_foreign_to_bzr(self._ref)
 
298
        return self.mapping.revision_id_foreign_to_bzr(self.head)
 
299
 
 
300
    def _get_config(self):
 
301
        class EmptyConfig(object):
 
302
 
 
303
            def _get_configobj(self):
 
304
                return config.ConfigObj()
 
305
 
 
306
        return EmptyConfig()
 
307
 
 
308
    @property
 
309
    def head(self):
 
310
        if self._ref is not None:
 
311
            return self._ref
 
312
        heads = self.repository.get_refs()
 
313
        if not self.name in heads:
 
314
            raise NoSuchRef(self.name)
 
315
        self._ref = heads[self.name]
 
316
        return self._ref
166
317
 
167
318
    def _synchronize_history(self, destination, revision_id):
168
319
        """See Branch._synchronize_history()."""
169
320
        destination.generate_revision_history(self.last_revision())
170
321
 
 
322
    def get_push_location(self):
 
323
        return None
 
324
 
 
325
    def set_push_location(self, url):
 
326
        pass