/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

Add description of git-v1 mapping.

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
    urlutils,
 
22
    )
 
23
from bzrlib.bzrdir import (
 
24
    BzrDir,
 
25
    BzrDirFormat,
 
26
    )
 
27
from bzrlib.errors import (
 
28
    BzrError,
 
29
    NoSuchFile,
 
30
    NotLocalUrl,
 
31
    )
 
32
from bzrlib.foreign import (
 
33
    ForeignBranch,
 
34
    )
 
35
from bzrlib.lockable_files import (
 
36
    TransportLock,
 
37
    )
 
38
from bzrlib.repository import (
 
39
    Repository,
 
40
    )
 
41
from bzrlib.trace import (
 
42
    info,
 
43
    )
 
44
from bzrlib.transport import (
 
45
    Transport,
 
46
    )
 
47
 
 
48
from bzrlib.plugins.git import (
 
49
    lazy_check_versions,
 
50
    )
 
51
lazy_check_versions()
 
52
 
 
53
from bzrlib.plugins.git.branch import (
 
54
    GitBranch,
 
55
    )
 
56
from bzrlib.plugins.git.errors import (
 
57
    GitSmartRemoteNotSupported,
 
58
    NoSuchRef,
 
59
    )
 
60
from bzrlib.plugins.git.dir import (
 
61
    GitDir,
 
62
    )
 
63
from bzrlib.plugins.git.repository import (
 
64
    GitRepositoryFormat,
 
65
    GitRepository,
 
66
    )
 
67
 
 
68
import dulwich as git
 
69
from dulwich.errors import (
 
70
    GitProtocolError,
 
71
    )
 
72
from dulwich.pack import (
 
73
    Pack,
 
74
    PackData,
 
75
    )
33
76
import os
34
77
import tempfile
35
78
import urllib
36
79
import urlparse
37
80
 
38
 
from dulwich.pack import PackData, Pack
 
81
try:
 
82
    from dulwich.pack import load_pack_index
 
83
except ImportError:
 
84
    from dulwich.pack import PackIndex as load_pack_index
 
85
 
 
86
 
 
87
# Don't run any tests on GitSmartTransport as it is not intended to be 
 
88
# a full implementation of Transport
 
89
def get_test_permutations():
 
90
    return []
39
91
 
40
92
 
41
93
class GitSmartTransport(Transport):
43
95
    def __init__(self, url, _client=None):
44
96
        Transport.__init__(self, url)
45
97
        (scheme, _, loc, _, _) = urlparse.urlsplit(url)
46
 
        assert scheme == "git"
47
98
        hostport, self._path = urllib.splithost(loc)
48
99
        (self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
49
100
        self._client = _client
50
101
 
 
102
    def has(self, relpath):
 
103
        return False
 
104
 
51
105
    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)
 
106
        raise NotImplementedError(self._get_client)
57
107
 
58
108
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
59
109
        if progress is None:
60
110
            def progress(text):
61
111
                info("git: %s" % text)
62
 
        self._get_client().fetch_pack(self._path, determine_wants, 
63
 
            graph_walker, pack_data, progress)
 
112
        client = self._get_client()
 
113
        try:
 
114
            client.fetch_pack(self._path, determine_wants, 
 
115
                graph_walker, pack_data, progress)
 
116
        except GitProtocolError, e:
 
117
            raise BzrError(e)
64
118
 
65
119
    def get(self, path):
66
120
        raise NoSuchFile(path)
75
129
        else:
76
130
            newurl = urlutils.join(self.base, offset)
77
131
 
78
 
        return GitSmartTransport(newurl, self._client)
 
132
        return self.__class__(newurl, self._client)
 
133
 
 
134
 
 
135
class TCPGitSmartTransport(GitSmartTransport):
 
136
 
 
137
    def _get_client(self):
 
138
        if self._client is not None:
 
139
            ret = self._client
 
140
            self._client = None
 
141
            return ret
 
142
        return git.client.TCPGitClient(self._host, self._port, thin_packs=False)
 
143
 
 
144
 
 
145
class SSHGitSmartTransport(GitSmartTransport):
 
146
 
 
147
    def _get_client(self):
 
148
        if self._client is not None:
 
149
            ret = self._client
 
150
            self._client = None
 
151
            return ret
 
152
        return git.client.SSHGitClient(self._host, self._port, thin_packs=False)
79
153
 
80
154
 
81
155
class RemoteGitDir(GitDir):
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
            self._data.create_index_v2(self._idx_path, self.resolve_ext_ref)
 
193
            self._idx = load_pack_index(self._idx_path)
 
194
        return self._idx
 
195
 
 
196
    def __del__(self):
 
197
        os.remove(self._data_path)
 
198
        os.remove(self._idx_path)
 
199
 
 
200
 
101
201
class RemoteGitRepository(GitRepository):
102
202
 
103
203
    def __init__(self, gitdir, lockfiles):
104
204
        GitRepository.__init__(self, gitdir, lockfiles)
 
205
        self._refs = None
 
206
 
 
207
    @property
 
208
    def inventories(self):
 
209
        raise GitSmartRemoteNotSupported()
 
210
 
 
211
    @property
 
212
    def revisions(self):
 
213
        raise GitSmartRemoteNotSupported()
 
214
 
 
215
    @property
 
216
    def texts(self):
 
217
        raise GitSmartRemoteNotSupported()
 
218
 
 
219
    def get_refs(self):
 
220
        if self._refs is not None:
 
221
            return self._refs
 
222
        def determine_wants(heads):
 
223
            self._refs = heads
 
224
            return []
 
225
        self.bzrdir.root_transport.fetch_pack(determine_wants, None, 
 
226
            lambda x: None, lambda x: mutter("git: %s" % x))
 
227
        return self._refs
105
228
 
106
229
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
107
230
                   progress=None):
108
231
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
109
232
            progress)
110
233
 
111
 
    def fetch_objects(self, determine_wants, graph_walker, progress=None):
 
234
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
112
235
        fd, path = tempfile.mkstemp(suffix=".pack")
113
236
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
114
237
        os.close(fd)
115
 
        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)
 
238
        if os.path.getsize(path) == 0:
 
239
            return EmptyObjectStoreIterator()
 
240
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
 
241
 
 
242
 
 
243
class RemoteGitTagDict(tag.BasicTags):
 
244
 
 
245
    def __init__(self, branch):
 
246
        self.branch = branch
 
247
        self.repository = branch.repository
 
248
 
 
249
    def get_tag_dict(self):
 
250
        ret = {}
 
251
        refs = self.repository.get_refs()
 
252
        for k,v in refs.iteritems():
 
253
            if k.startswith("refs/tags/") and not k.endswith("^{}"):
 
254
                v = refs.get(k+"^{}", v)
 
255
                ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
 
256
        return ret
 
257
 
 
258
    def set_tag(self, name, revid):
 
259
        # FIXME: Not supported yet, should do a push of a new ref
 
260
        raise NotImplementedError(self.set_tag)
123
261
 
124
262
 
125
263
class RemoteGitBranch(GitBranch):
126
264
 
127
265
    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))
 
266
        heads = repository.get_refs()
 
267
        if not name in heads:
 
268
            raise NoSuchRef(name)
 
269
        self._ref = heads[name]
134
270
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
135
271
 
136
272
    def last_revision(self):