15
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
from bzrlib import urlutils
18
from bzrlib import branch, tag, urlutils
19
19
from bzrlib.bzrdir import BzrDir, BzrDirFormat
20
from bzrlib.errors import NoSuchFile, NotLocalUrl
20
from bzrlib.errors import BzrError, NoSuchFile, NotLocalUrl
21
21
from bzrlib.lockable_files import TransportLock
22
22
from bzrlib.repository import Repository
23
23
from bzrlib.trace import info
56
57
(self._host, self._port) = urllib.splitnport(hostport, git.protocol.TCP_GIT_PORT)
57
58
self._client = _client
60
def has(self, relpath):
59
63
def _get_client(self):
60
64
if self._client is not None:
62
66
self._client = None
64
return git.client.TCPGitClient(self._host, self._port)
68
return git.client.TCPGitClient(self._host, self._port, thin_packs=False)
66
70
def fetch_pack(self, determine_wants, graph_walker, pack_data, progress=None):
67
71
if progress is None:
68
72
def progress(text):
69
73
info("git: %s" % text)
70
self._get_client().fetch_pack(self._path, determine_wants,
71
graph_walker, pack_data, progress)
74
client = self._get_client()
76
client.fetch_pack(self._path, determine_wants,
77
graph_walker, pack_data, progress)
78
except GitProtocolError, e:
73
81
def get(self, path):
74
82
raise NoSuchFile(path)
106
114
raise NotLocalUrl(self.transport.base)
109
class TemporaryPackIterator(object):
111
def __init__(self, path):
112
self.path_data = path
113
basename = path[:-len(".pack")]
115
self.path_idx = basename+".idx"
116
p.create_index_v2(self.path_idx)
117
self.pack = Pack(basename)
118
self._iter = self.pack.iterobjects()
117
class EmptyObjectStoreIterator(dict):
119
def iterobjects(self):
123
class TemporaryPackIterator(Pack):
125
def __init__(self, path, resolve_ext_ref):
126
self.resolve_ext_ref = resolve_ext_ref
127
super(TemporaryPackIterator, self).__init__(path)
131
if self._idx is None:
132
self._data.create_index_v2(self._idx_path, self.resolve_ext_ref)
133
self._idx = PackIndex(self._idx_path)
120
136
def __del__(self):
121
os.remove(self.path_data)
122
os.remove(self.path_idx)
125
return (self._iter.next(), None)
128
return len(self.pack)
137
os.remove(self._data_path)
138
os.remove(self._idx_path)
131
141
class RemoteGitRepository(GitRepository):
133
143
def __init__(self, gitdir, lockfiles):
134
144
GitRepository.__init__(self, gitdir, lockfiles)
148
if self._refs is not None:
150
def determine_wants(heads):
153
self.bzrdir.root_transport.fetch_pack(determine_wants, None,
154
lambda x: None, lambda x: mutter("git: %s" % x))
136
157
def fetch_pack(self, determine_wants, graph_walker, pack_data,
138
159
self._transport.fetch_pack(determine_wants, graph_walker, pack_data,
141
def fetch_objects(self, determine_wants, graph_walker, progress=None):
162
def fetch_objects(self, determine_wants, graph_walker, resolve_ext_ref, progress=None):
142
163
fd, path = tempfile.mkstemp(suffix=".pack")
143
164
self.fetch_pack(determine_wants, graph_walker, lambda x: os.write(fd, x), progress)
145
ret = TemporaryPackIterator(path)
146
return (len(ret), iter(ret.next, None))
166
if os.path.getsize(path) == 0:
167
return EmptyObjectStoreIterator()
168
return TemporaryPackIterator(path[:-len(".pack")], resolve_ext_ref)
171
class RemoteGitTagDict(tag.BasicTags):
173
def __init__(self, branch):
175
self.repository = branch.repository
177
def get_tag_dict(self):
179
refs = self.repository.get_refs()
180
for k,v in refs.iteritems():
181
if k.startswith("refs/tags/") and not k.endswith("^{}"):
182
v = refs.get(k+"^{}", v)
183
ret[k[len("refs/tags/"):]] = self.branch.mapping.revision_id_foreign_to_bzr(v)
186
def set_tag(self, name, revid):
187
# FIXME: Not supported yet, should do a push of a new ref
188
raise NotImplementedError(self.set_tag)
149
191
class RemoteGitBranch(GitBranch):
151
193
def __init__(self, bzrdir, repository, name, lockfiles):
152
def determine_wants(heads):
153
if not name in heads:
154
raise NoSuchRef(name)
155
self._ref = heads[name]
156
bzrdir.root_transport.fetch_pack(determine_wants, None, lambda x: None,
157
lambda x: mutter("git: %s" % x))
194
heads = repository.get_refs()
195
if not name in heads:
196
raise NoSuchRef(name)
197
self._ref = heads[name]
158
198
super(RemoteGitBranch, self).__init__(bzrdir, repository, name, self._ref, lockfiles)
160
200
def last_revision(self):