/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

SupportĀ parsingĀ .gitignore.

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