/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

Try to import nothing other than __init__ when not opening git repositories.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2007-2009 Jelmer Vernooij <jelmer@samba.org>
 
1
# Copyright (C) 2007-2008 Canonical Ltd
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 (
19
 
    branch,
20
 
    tag,
21
 
    ui,
22
 
    urlutils,
23
 
    )
24
 
from bzrlib.errors import (
25
 
    BzrError,
26
 
    InvalidRevisionId,
27
 
    NoSuchFile,
28
 
    NoSuchRevision,
29
 
    NotLocalUrl,
30
 
    )
31
 
from bzrlib.trace import (
32
 
    info,
33
 
    )
34
 
from bzrlib.transport import (
35
 
    Transport,
36
 
    )
 
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
37
25
 
38
 
from bzrlib.plugins.git import (
39
 
    lazy_check_versions,
40
 
    )
 
26
from bzrlib.plugins.git import lazy_check_versions
41
27
lazy_check_versions()
42
28
 
43
 
from bzrlib.plugins.git.branch import (
44
 
    GitBranch,
45
 
    extract_tags,
46
 
    )
47
 
from bzrlib.plugins.git.errors import (
48
 
    GitSmartRemoteNotSupported,
49
 
    NoSuchRef,
50
 
    )
51
 
from bzrlib.plugins.git.dir import (
52
 
    GitDir,
53
 
    )
54
 
from bzrlib.plugins.git.mapping import (
55
 
    mapping_registry,
56
 
    )
57
 
from bzrlib.plugins.git.repository import (
58
 
    GitRepositoryFormat,
59
 
    GitRepository,
60
 
    )
 
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
61
34
 
62
 
import dulwich as git
63
 
from dulwich.errors import (
64
 
    GitProtocolError,
65
 
    )
66
 
from dulwich.pack import (
67
 
    Pack,
68
 
    PackData,
69
 
    )
70
35
import os
71
36
import tempfile
72
37
import urllib
73
38
import urlparse
74
39
 
75
 
try:
76
 
    from dulwich.pack import load_pack_index
77
 
except ImportError:
78
 
    from dulwich.pack import PackIndex as load_pack_index
79
 
 
 
40
import dulwich as git
 
41
from dulwich.pack import PackData, Pack
80
42
 
81
43
# Don't run any tests on GitSmartTransport as it is not intended to be 
82
44
# a full implementation of Transport
89
51
    def __init__(self, url, _client=None):
90
52
        Transport.__init__(self, url)
91
53
        (scheme, _, loc, _, _) = urlparse.urlsplit(url)
 
54
        assert scheme == "git"
92
55
        hostport, self._path = urllib.splithost(loc)
93
 
        (self._host, self._port) = urllib.splitnport(hostport, None)
 
56
        (self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
94
57
        self._client = _client
95
58
 
96
 
    def has(self, relpath):
97
 
        return False
98
 
 
99
59
    def _get_client(self):
100
 
        raise NotImplementedError(self._get_client)
 
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)
101
65
 
102
66
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
103
67
        if progress is None:
104
68
            def progress(text):
105
69
                info("git: %s" % text)
106
 
        client = self._get_client()
107
 
        try:
108
 
            return client.fetch_pack(self._path, determine_wants, 
109
 
                graph_walker, pack_data, progress)
110
 
        except GitProtocolError, e:
111
 
            raise BzrError(e)
112
 
 
113
 
    def send_pack(self, get_changed_refs, generate_pack_contents):
114
 
        client = self._get_client()
115
 
        try:
116
 
            return client.send_pack(self._path, get_changed_refs, 
117
 
                generate_pack_contents)
118
 
        except GitProtocolError, e:
119
 
            raise BzrError(e)
 
70
        self._get_client().fetch_pack(self._path, determine_wants, 
 
71
            graph_walker, pack_data, progress)
120
72
 
121
73
    def get(self, path):
122
74
        raise NoSuchFile(path)
131
83
        else:
132
84
            newurl = urlutils.join(self.base, offset)
133
85
 
134
 
        return self.__class__(newurl, self._client)
135
 
 
136
 
 
137
 
class TCPGitSmartTransport(GitSmartTransport):
138
 
 
139
 
    _scheme = 'git'
140
 
 
141
 
    def _get_client(self):
142
 
        if self._client is not None:
143
 
            ret = self._client
144
 
            self._client = None
145
 
            return ret
146
 
        return git.client.TCPGitClient(self._host, self._port, thin_packs=False,
147
 
            report_activity=self._report_activity)
148
 
 
149
 
 
150
 
class SSHGitSmartTransport(GitSmartTransport):
151
 
 
152
 
    _scheme = 'git+ssh'
153
 
 
154
 
    def _get_client(self):
155
 
        if self._client is not None:
156
 
            ret = self._client
157
 
            self._client = None
158
 
            return ret
159
 
        return git.client.SSHGitClient(self._host, self._port, thin_packs=False,
160
 
            report_activity=self._report_activity)
 
86
        return GitSmartTransport(newurl, self._client)
161
87
 
162
88
 
163
89
class RemoteGitDir(GitDir):
167
93
        self.root_transport = transport
168
94
        self.transport = transport
169
95
        self._lockfiles = lockfiles
170
 
        self._mode_check_done = None
171
96
 
172
97
    def open_repository(self):
173
98
        return RemoteGitRepository(self, self._lockfiles)
174
99
 
175
 
    def open_branch(self, ignore_fallbacks=False):
 
100
    def open_branch(self, _unsupported=False):
176
101
        repo = self.open_repository()
177
102
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
178
103
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
181
106
        raise NotLocalUrl(self.transport.base)
182
107
 
183
108
 
184
 
class EmptyObjectStoreIterator(dict):
185
 
 
186
 
    def iterobjects(self):
187
 
        return []
188
 
 
189
 
 
190
 
class TemporaryPackIterator(Pack):
191
 
 
192
 
    def __init__(self, path, resolve_ext_ref):
193
 
        super(TemporaryPackIterator, self).__init__(path)
194
 
        self.resolve_ext_ref = resolve_ext_ref
195
 
 
196
 
    @property
197
 
    def index(self):
198
 
        if self._idx is None:
199
 
            if self._data is None:
200
 
                self._data = PackData(self._data_path)
201
 
            pb = ui.ui_factory.nested_progress_bar()
202
 
            try:
203
 
                def report_progress(cur, total):
204
 
                    pb.update("generating index", cur, total)
205
 
                self._data.create_index_v2(self._idx_path, self.resolve_ext_ref,
206
 
                    progress=report_progress)
207
 
            finally:
208
 
                pb.finished()
209
 
            self._idx = load_pack_index(self._idx_path)
210
 
        return self._idx
211
 
 
212
 
    def __del__(self):
213
 
        os.remove(self._data_path)
214
 
        os.remove(self._idx_path)
215
 
 
216
 
 
217
109
class RemoteGitRepository(GitRepository):
218
110
 
219
111
    def __init__(self, gitdir, lockfiles):
220
112
        GitRepository.__init__(self, gitdir, lockfiles)
221
 
        self._refs = None
222
 
 
223
 
    @property
224
 
    def inventories(self):
225
 
        raise GitSmartRemoteNotSupported()
226
 
 
227
 
    @property
228
 
    def revisions(self):
229
 
        raise GitSmartRemoteNotSupported()
230
 
 
231
 
    @property
232
 
    def texts(self):
233
 
        raise GitSmartRemoteNotSupported()
234
 
 
235
 
    def get_refs(self):
236
 
        if self._refs is not None:
237
 
            return self._refs
238
 
        self._refs = self.bzrdir.root_transport.fetch_pack(lambda x: [], None, 
239
 
            lambda x: None, lambda x: mutter("git: %s" % x))
240
 
        return self._refs
241
113
 
242
114
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
243
115
                   progress=None):
244
 
        return self._transport.fetch_pack(determine_wants, graph_walker,
245
 
                                          pack_data, progress)
246
 
 
247
 
    def send_pack(self, get_changed_refs, generate_pack_contents):
248
 
        return self._transport.send_pack(get_changed_refs, generate_pack_contents)
249
 
 
250
 
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
 
116
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
 
117
            progress)
 
118
 
 
119
    def fetch_objects(self, determine_wants, graph_walker, progress=None):
251
120
        fd, path = tempfile.mkstemp(suffix=".pack")
252
121
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
253
122
        os.close(fd)
254
 
        if os.path.getsize(path) == 0:
255
 
            return EmptyObjectStoreIterator()
256
 
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
257
 
 
258
 
    def lookup_git_revid(self, bzr_revid):
259
 
        # This won't work for any round-tripped bzr revisions, but it's a start..
260
 
        try:
261
 
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
262
 
        except InvalidRevisionId:
263
 
            raise NoSuchRevision(self, bzr_revid)
264
 
 
265
 
 
266
 
class RemoteGitTagDict(tag.BasicTags):
267
 
 
268
 
    def __init__(self, branch):
269
 
        self.branch = branch
270
 
        self.repository = branch.repository
271
 
 
272
 
    def get_tag_dict(self):
273
 
        return extract_tags(self.repository.get_refs(), self.branch.mapping)
274
 
 
275
 
    def set_tag(self, name, revid):
276
 
        # FIXME: Not supported yet, should do a push of a new ref
277
 
        raise NotImplementedError(self.set_tag)
 
123
        basename = path[:-len(".pack")]
 
124
        p = PackData(path)
 
125
        p.create_index_v2(basename+".idx")
 
126
        pack = Pack(basename)
 
127
        os.remove(path)
 
128
        return (len(p), pack.iterobjects())
278
129
 
279
130
 
280
131
class RemoteGitBranch(GitBranch):
281
132
 
282
133
    def __init__(self, bzrdir, repository, name, lockfiles):
283
 
        self._ref = None
284
 
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, 
285
 
                lockfiles)
286
 
 
287
 
    def revision_history(self):
288
 
        raise GitSmartRemoteNotSupported()
 
134
        def determine_wants(heads):
 
135
            if not name in heads:
 
136
                raise NoSuchRef(name)
 
137
            self._ref = heads[name]
 
138
        bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None, 
 
139
                             lambda x: mutter("git: %s" % x))
 
140
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
289
141
 
290
142
    def last_revision(self):
291
 
        return self.mapping.revision_id_foreign_to_bzr(self.head)
292
 
 
293
 
    @property
294
 
    def head(self):
295
 
        if self._ref is None:
296
 
            return self._ref
297
 
        heads = repository.get_refs()
298
 
        if not name in heads:
299
 
            raise NoSuchRef(name)
300
 
        self._ref = heads[name]
301
 
        return self._ref
 
143
        return self.mapping.revision_id_foreign_to_bzr(self._ref)
302
144
 
303
145
    def _synchronize_history(self, destination, revision_id):
304
146
        """See Branch._synchronize_history()."""