15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from bzrlib import urlutils
19
from bzrlib.bzrdir import BzrDir, BzrDirFormat
20
from bzrlib.errors import NoSuchFile, NotLocalUrl
23
from bzrlib.bzrdir import (
27
from bzrlib.errors import (
21
32
from bzrlib.lockable_files import TransportLock
22
33
from bzrlib.repository import Repository
23
34
from bzrlib.trace import info
24
35
from bzrlib.transport import Transport
26
from bzrlib.plugins.git import git
37
from bzrlib.plugins.git import lazy_check_versions
27
40
from bzrlib.plugins.git.branch import GitBranch
28
41
from bzrlib.plugins.git.errors import NoSuchRef
29
42
from bzrlib.plugins.git.dir import GitDir
30
43
from bzrlib.plugins.git.foreign import ForeignBranch
31
from bzrlib.plugins.git.repository import GitFormat, GitRepository
44
from bzrlib.plugins.git.repository import (
50
from dulwich.errors import GitProtocolError
51
from dulwich.pack import (
38
from dulwich.pack import PackData, Pack
62
# Don't run any tests on GitSmartTransport as it is not intended to be
63
# a full implementation of Transport
64
def get_test_permutations():
41
68
class GitSmartTransport(Transport):
48
75
(self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
49
76
self._client = _client
78
def has(self, relpath):
51
81
def _get_client(self):
52
82
if self._client is not None:
54
84
self._client = None
56
return git.client.TCPGitClient(self._host, self._port)
86
return git.client.TCPGitClient(self._host, self._port, thin_packs=False)
58
88
def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
59
89
if progress is None:
60
90
def progress(text):
61
91
info("git: %s" % text)
62
self._get_client().fetch_pack(self._path, determine_wants,
63
graph_walker, pack_data, progress)
92
client = self._get_client()
94
client.fetch_pack(self._path, determine_wants,
95
graph_walker, pack_data, progress)
96
except GitProtocolError, e:
65
99
def get(self, path):
66
100
raise NoSuchFile(path)
98
132
raise NotLocalUrl(self.transport.base)
135
class EmptyObjectStoreIterator(dict):
137
def iterobjects(self):
141
class TemporaryPackIterator(Pack):
143
def __init__(self, path, resolve_ext_ref):
144
self.resolve_ext_ref = resolve_ext_ref
145
super(TemporaryPackIterator, self).__init__(path)
149
if self._idx is None:
150
self._data.create_index_v2(self._idx_path, self.resolve_ext_ref)
151
self._idx = PackIndex(self._idx_path)
155
os.remove(self._data_path)
156
os.remove(self._idx_path)
101
159
class RemoteGitRepository(GitRepository):
103
161
def __init__(self, gitdir, lockfiles):
104
162
GitRepository.__init__(self, gitdir, lockfiles)
166
if self._refs is not None:
168
def determine_wants(heads):
171
self.bzrdir.root_transport.fetch_pack(determine_wants, None,
172
lambda x: None, lambda x: mutter("git: %s" % x))
106
175
def fetch_pack(self, determine_wants, graph_walker, pack_data,
108
177
self._transport.fetch_pack(determine_wants, graph_walker, pack_data,
111
def fetch_objects(self, determine_wants, graph_walker, progress=None):
180
def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
112
181
fd, path = tempfile.mkstemp(suffix=".pack")
113
182
self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
116
basename = path[:-len(".pack")]
118
p.create_index_v2(basename+".idx")
119
for o in Pack(basename).iterobjects():
184
if os.path.getsize(path) == 0:
185
return EmptyObjectStoreIterator()
186
return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
189
class RemoteGitTagDict(tag.BasicTags):
191
def __init__(self, branch):
193
self.repository = branch.repository
195
def get_tag_dict(self):
197
refs = self.repository.get_refs()
198
for k,v in refs.iteritems():
199
if k.startswith("refs/tags/") and not k.endswith("^{}"):
200
v = refs.get(k+"^{}", v)
201
ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
204
def set_tag(self, name, revid):
205
# FIXME: Not supported yet, should do a push of a new ref
206
raise NotImplementedError(self.set_tag)
125
209
class RemoteGitBranch(GitBranch):
127
211
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))
212
heads = repository.get_refs()
213
if not name in heads:
214
raise NoSuchRef(name)
215
self._ref = heads[name]
134
216
super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
136
218
def last_revision(self):