/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

Remove silly mapping of timezones; dulwich uses offsets now as well.

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)
 
111
 
 
112
    def send_pack(self, get_changed_refs, generate_pack_contents):
 
113
        client = self._get_client()
 
114
        try:
 
115
            client.send_pack(self._path, get_changed_refs, 
 
116
                generate_pack_contents)
 
117
        except GitProtocolError, e:
 
118
            raise BzrError(e)
64
119
 
65
120
    def get(self, path):
66
121
        raise NoSuchFile(path)
75
130
        else:
76
131
            newurl = urlutils.join(self.base, offset)
77
132
 
78
 
        return GitSmartTransport(newurl, self._client)
 
133
        return self.__class__(newurl, self._client)
 
134
 
 
135
 
 
136
class TCPGitSmartTransport(GitSmartTransport):
 
137
 
 
138
    _scheme = 'git'
 
139
 
 
140
    def _get_client(self):
 
141
        if self._client is not None:
 
142
            ret = self._client
 
143
            self._client = None
 
144
            return ret
 
145
        return git.client.TCPGitClient(self._host, self._port, thin_packs=False,
 
146
            report_activity=self._report_activity)
 
147
 
 
148
 
 
149
class SSHGitSmartTransport(GitSmartTransport):
 
150
 
 
151
    _scheme = 'git+ssh'
 
152
 
 
153
    def _get_client(self):
 
154
        if self._client is not None:
 
155
            ret = self._client
 
156
            self._client = None
 
157
            return ret
 
158
        return git.client.SSHGitClient(self._host, self._port, thin_packs=False,
 
159
            report_activity=self._report_activity)
79
160
 
80
161
 
81
162
class RemoteGitDir(GitDir):
85
166
        self.root_transport = transport
86
167
        self.transport = transport
87
168
        self._lockfiles = lockfiles
 
169
        self._mode_check_done = None
88
170
 
89
171
    def open_repository(self):
90
172
        return RemoteGitRepository(self, self._lockfiles)
91
173
 
92
 
    def open_branch(self):
 
174
    def open_branch(self, ignore_fallbacks=False):
93
175
        repo = self.open_repository()
94
176
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
95
177
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
98
180
        raise NotLocalUrl(self.transport.base)
99
181
 
100
182
 
 
183
class EmptyObjectStoreIterator(dict):
 
184
 
 
185
    def iterobjects(self):
 
186
        return []
 
187
 
 
188
 
 
189
class TemporaryPackIterator(Pack):
 
190
 
 
191
    def __init__(self, path, resolve_ext_ref):
 
192
        super(TemporaryPackIterator, self).__init__(path)
 
193
        self.resolve_ext_ref = resolve_ext_ref
 
194
 
 
195
    @property
 
196
    def idx(self):
 
197
        if self._idx is None:
 
198
            if self._data is None:
 
199
                self._data = PackData(self._data_path)
 
200
            pb = ui.ui_factory.nested_progress_bar()
 
201
            try:
 
202
                def report_progress(cur, total):
 
203
                    pb.update("generating index", cur, total)
 
204
                self._data.create_index_v2(self._idx_path, self.resolve_ext_ref,
 
205
                    progress=report_progress)
 
206
            finally:
 
207
                pb.finished()
 
208
            self._idx = load_pack_index(self._idx_path)
 
209
        return self._idx
 
210
 
 
211
    def __del__(self):
 
212
        os.remove(self._data_path)
 
213
        os.remove(self._idx_path)
 
214
 
 
215
 
101
216
class RemoteGitRepository(GitRepository):
102
217
 
103
218
    def __init__(self, gitdir, lockfiles):
104
219
        GitRepository.__init__(self, gitdir, lockfiles)
 
220
        self._refs = None
 
221
 
 
222
    @property
 
223
    def inventories(self):
 
224
        raise GitSmartRemoteNotSupported()
 
225
 
 
226
    @property
 
227
    def revisions(self):
 
228
        raise GitSmartRemoteNotSupported()
 
229
 
 
230
    @property
 
231
    def texts(self):
 
232
        raise GitSmartRemoteNotSupported()
 
233
 
 
234
    def get_refs(self):
 
235
        if self._refs is not None:
 
236
            return self._refs
 
237
        def determine_wants(heads):
 
238
            self._refs = heads
 
239
            return []
 
240
        self.bzrdir.root_transport.fetch_pack(determine_wants, None, 
 
241
            lambda x: None, lambda x: mutter("git: %s" % x))
 
242
        return self._refs
105
243
 
106
244
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
107
245
                   progress=None):
108
246
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
109
247
            progress)
110
248
 
111
 
    def fetch_objects(self, determine_wants, graph_walker, progress=None):
 
249
    def send_pack(self, get_changed_refs, generate_pack_contents):
 
250
        self._transport.send_pack(get_changed_refs, generate_pack_contents)
 
251
 
 
252
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
112
253
        fd, path = tempfile.mkstemp(suffix=".pack")
113
254
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
114
255
        os.close(fd)
 
256
        if os.path.getsize(path) == 0:
 
257
            return EmptyObjectStoreIterator()
 
258
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
 
259
 
 
260
    def lookup_git_revid(self, bzr_revid):
 
261
        # This won't work for any round-tripped bzr revisions, but it's a start..
115
262
        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)
 
263
            return mapping_registry.revision_id_bzr_to_foreign(bzr_revid)
 
264
        except InvalidRevisionId:
 
265
            raise NoSuchRevision(self, bzr_revid)
 
266
 
 
267
 
 
268
class RemoteGitTagDict(tag.BasicTags):
 
269
 
 
270
    def __init__(self, branch):
 
271
        self.branch = branch
 
272
        self.repository = branch.repository
 
273
 
 
274
    def get_tag_dict(self):
 
275
        ret = {}
 
276
        refs = self.repository.get_refs()
 
277
        for k,v in refs.iteritems():
 
278
            if k.startswith("refs/tags/") and not k.endswith("^{}"):
 
279
                v = refs.get(k+"^{}", v)
 
280
                ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
 
281
        return ret
 
282
 
 
283
    def set_tag(self, name, revid):
 
284
        # FIXME: Not supported yet, should do a push of a new ref
 
285
        raise NotImplementedError(self.set_tag)
123
286
 
124
287
 
125
288
class RemoteGitBranch(GitBranch):
126
289
 
127
290
    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))
 
291
        heads = repository.get_refs()
 
292
        if not name in heads:
 
293
            raise NoSuchRef(name)
 
294
        self._ref = heads[name]
134
295
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
135
296
 
 
297
    def revision_history(self):
 
298
        raise GitSmartRemoteNotSupported()
 
299
 
136
300
    def last_revision(self):
137
301
        return self.mapping.revision_id_foreign_to_bzr(self._ref)
138
302