/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

Fix import of RemoteGitRepository.

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