/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

  • Committer: Jelmer Vernooij
  • Date: 2009-03-28 22:27:07 UTC
  • mto: (0.200.305 trunk)
  • mto: This revision was merged to the branch mainline in revision 6960.
  • Revision ID: jelmer@samba.org-20090328222707-n0y980ntev40xqd2
Fix blob lookup.

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.dir import GitDir
29
 
from bzrlib.plugins.git.foreign import ForeignBranch
30
 
from bzrlib.plugins.git.repository import GitFormat, GitRepository
31
 
 
 
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.lockable_files import (
 
33
    TransportLock,
 
34
    )
 
35
from bzrlib.repository import (
 
36
    Repository,
 
37
    )
 
38
from bzrlib.trace import (
 
39
    info,
 
40
    )
 
41
from bzrlib.transport import (
 
42
    Transport,
 
43
    )
 
44
 
 
45
from bzrlib.plugins.git import (
 
46
    lazy_check_versions,
 
47
    )
 
48
lazy_check_versions()
 
49
 
 
50
from bzrlib.plugins.git.branch import (
 
51
    GitBranch,
 
52
    )
 
53
from bzrlib.plugins.git.errors import (
 
54
    NoSuchRef,
 
55
    )
 
56
from bzrlib.plugins.git.dir import (
 
57
    GitDir,
 
58
    )
 
59
from bzrlib.plugins.git.foreign import (
 
60
    ForeignBranch,
 
61
    )
 
62
from bzrlib.plugins.git.repository import (
 
63
    GitRepositoryFormat,
 
64
    GitRepository,
 
65
    )
 
66
 
 
67
import dulwich as git
 
68
from dulwich.errors import (
 
69
    GitProtocolError,
 
70
    )
 
71
from dulwich.pack import (
 
72
    Pack,
 
73
    PackData,
 
74
    PackIndex,
 
75
    )
 
76
import os
 
77
import tempfile
32
78
import urllib
33
79
import urlparse
34
80
 
35
 
from dulwich.pack import PackData
 
81
 
 
82
# Don't run any tests on GitSmartTransport as it is not intended to be 
 
83
# a full implementation of Transport
 
84
def get_test_permutations():
 
85
    return []
36
86
 
37
87
 
38
88
class GitSmartTransport(Transport):
43
93
        assert scheme == "git"
44
94
        hostport, self._path = urllib.splithost(loc)
45
95
        (self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
46
 
        if _client is not None:
47
 
            self._client = _client
48
 
        else:
49
 
            self._client = git.client.TCPGitClient(self._host, self._port)
 
96
        self._client = _client
 
97
 
 
98
    def has(self, relpath):
 
99
        return False
 
100
 
 
101
    def _get_client(self):
 
102
        if self._client is not None:
 
103
            ret = self._client
 
104
            self._client = None
 
105
            return ret
 
106
        return git.client.TCPGitClient(self._host, self._port, thin_packs=False)
50
107
 
51
108
    def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
52
109
        if progress is None:
53
110
            def progress(text):
54
111
                info("git: %s" % text)
55
 
        self._client.fetch_pack(self._path, determine_wants, graph_walker, 
56
 
                pack_data, progress)
57
 
 
58
 
    def fetch_objects(self, determine_wants, graph_walker, progress=None):
59
 
        fd, path = tempfile.mkstemp(dir=self.pack_dir(), suffix=".pack")
60
 
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
61
 
        os.close(fd)
 
112
        client = self._get_client()
62
113
        try:
63
 
            p = PackData(path)
64
 
            for o in p.iterobjects():
65
 
                yield o
66
 
        finally:
67
 
            os.remove(path)
 
114
            client.fetch_pack(self._path, determine_wants, 
 
115
                graph_walker, pack_data, progress)
 
116
        except GitProtocolError, e:
 
117
            raise BzrError(e)
68
118
 
69
119
    def get(self, path):
70
120
        raise NoSuchFile(path)
71
121
 
 
122
    def abspath(self, relpath):
 
123
        return urlutils.join(self.base, relpath)
 
124
 
72
125
    def clone(self, offset=None):
73
126
        """See Transport.clone()."""
74
127
        if offset is None:
90
143
    def open_repository(self):
91
144
        return RemoteGitRepository(self, self._lockfiles)
92
145
 
93
 
    def open_branch(self):
 
146
    def open_branch(self, _unsupported=False):
94
147
        repo = self.open_repository()
95
148
        # TODO: Support for multiple branches in one bzrdir in bzrlib!
96
149
        return RemoteGitBranch(self, repo, "HEAD", self._lockfiles)
99
152
        raise NotLocalUrl(self.transport.base)
100
153
 
101
154
 
 
155
class EmptyObjectStoreIterator(dict):
 
156
 
 
157
    def iterobjects(self):
 
158
        return []
 
159
 
 
160
 
 
161
class TemporaryPackIterator(Pack):
 
162
 
 
163
    def __init__(self, path, resolve_ext_ref):
 
164
        self.resolve_ext_ref = resolve_ext_ref
 
165
        super(TemporaryPackIterator, self).__init__(path)
 
166
 
 
167
    @property
 
168
    def idx(self):
 
169
        if self._idx is None:
 
170
            if self._data is None:
 
171
                self._data = PackData(self._data_path)
 
172
            self._data.create_index_v2(self._idx_path, self.resolve_ext_ref)
 
173
            self._idx = PackIndex(self._idx_path)
 
174
        return self._idx
 
175
 
 
176
    def __del__(self):
 
177
        os.remove(self._data_path)
 
178
        os.remove(self._idx_path)
 
179
 
 
180
 
102
181
class RemoteGitRepository(GitRepository):
103
182
 
104
183
    def __init__(self, gitdir, lockfiles):
105
184
        GitRepository.__init__(self, gitdir, lockfiles)
 
185
        self._refs = None
 
186
 
 
187
    def get_refs(self):
 
188
        if self._refs is not None:
 
189
            return self._refs
 
190
        def determine_wants(heads):
 
191
            self._refs = heads
 
192
            return []
 
193
        self.bzrdir.root_transport.fetch_pack(determine_wants, None, 
 
194
            lambda x: None, lambda x: mutter("git: %s" % x))
 
195
        return self._refs
106
196
 
107
197
    def fetch_pack(self, determine_wants, graph_walker, pack_data, 
108
198
                   progress=None):
109
199
        self._transport.fetch_pack(determine_wants, graph_walker, pack_data, 
110
200
            progress)
111
201
 
 
202
    def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
 
203
        fd, path = tempfile.mkstemp(suffix=".pack")
 
204
        self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
 
205
        os.close(fd)
 
206
        if os.path.getsize(path) == 0:
 
207
            return EmptyObjectStoreIterator()
 
208
        return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
 
209
 
 
210
 
 
211
class RemoteGitTagDict(tag.BasicTags):
 
212
 
 
213
    def __init__(self, branch):
 
214
        self.branch = branch
 
215
        self.repository = branch.repository
 
216
 
 
217
    def get_tag_dict(self):
 
218
        ret = {}
 
219
        refs = self.repository.get_refs()
 
220
        for k,v in refs.iteritems():
 
221
            if k.startswith("refs/tags/") and not k.endswith("^{}"):
 
222
                v = refs.get(k+"^{}", v)
 
223
                ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
 
224
        return ret
 
225
 
 
226
    def set_tag(self, name, revid):
 
227
        # FIXME: Not supported yet, should do a push of a new ref
 
228
        raise NotImplementedError(self.set_tag)
 
229
 
112
230
 
113
231
class RemoteGitBranch(GitBranch):
114
232
 
115
233
    def __init__(self, bzrdir, repository, name, lockfiles):
116
 
        def determine_wants(heads):
117
 
            self._ref = heads[name]
118
 
        bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None, 
119
 
                             lambda x: mutter("git: %s" % x))
 
234
        heads = repository.get_refs()
 
235
        if not name in heads:
 
236
            raise NoSuchRef(name)
 
237
        self._ref = heads[name]
120
238
        super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
121
239
 
122
240
    def last_revision(self):
123
241
        return self.mapping.revision_id_foreign_to_bzr(self._ref)
124
242
 
 
243
    def _synchronize_history(self, destination, revision_id):
 
244
        """See Branch._synchronize_history()."""
 
245
        destination.generate_revision_history(self.last_revision())
 
246