70
67
def __repr__(self):
71
68
return "%s(%r)" % (self.__class__.__name__, self.transport)
73
def _ensure_dir_exists(self, path):
74
for n in range(path.count("/")):
75
dirname = "/".join(path.split("/")[:n+1])
77
self.transport.mkdir(dirname)
81
70
def subkeys(self, base):
72
path = self.refpath(base)
84
74
iter_files = self.transport.clone(base).iter_files_recursive()
85
keys.update(("%s/%s" % (base, refname)).strip("/") for
86
refname in iter_files if check_ref_format("%s/%s" % (base, refname)))
87
except (TransportNotPossible, NoSuchFile):
75
except TransportNotPossible:
78
for refname in iter_files:
79
# check_ref_format requires at least one /, so we prepend the
80
# base before calling it.
81
if check_ref_format("%s/%s" % (base, refname)):
82
keys.add(("%s/%s" % refname).strip("/"))
89
83
for key in self.get_packed_refs():
90
84
if key.startswith(base):
91
85
keys.add(key[len(base):].strip("/"))
96
90
if self.transport.has("HEAD"):
99
iter_files = list(self.transport.clone("refs").iter_files_recursive())
100
for filename in iter_files:
101
refname = "refs/%s" % filename
94
iter_files = self.transport.clone("refs").iter_files_recursive()
95
except TransportNotPossible:
98
for refname in iter_files:
102
99
if check_ref_format(refname):
103
100
keys.add(refname)
104
except (TransportNotPossible, NoSuchFile):
106
101
keys.update(self.get_packed_refs())
198
193
del self._packed_refs[name]
199
194
if name in self._peeled_refs:
200
195
del self._peeled_refs[name]
201
f = self.transport.open_write_stream("packed-refs")
203
write_packed_refs(f, self._packed_refs, self._peeled_refs)
197
write_packed_refs(f, self._packed_refs, self._peeled_refs)
199
self.transport.put_file("packed-refs", f)
207
201
def set_symbolic_ref(self, name, other):
208
202
"""Make a ref point at another ref.
213
207
self._check_refname(name)
214
208
self._check_refname(other)
215
self._ensure_dir_exists(name)
216
209
self.transport.put_bytes(name, SYMREF + other + '\n')
218
211
def set_if_equals(self, name, old_ref, new_ref):
231
224
realname, _ = self._follow(name)
234
self._ensure_dir_exists(realname)
235
self.transport.put_bytes(realname, new_ref+"\n")
227
self.transport.put_bytes_non_atomic(realname, new_ref+"\n",
228
create_parent_dir=True)
238
231
def add_if_new(self, name, ref):
254
247
self._check_refname(realname)
255
self._ensure_dir_exists(realname)
256
self.transport.put_bytes(realname, ref+"\n")
248
self.transport.put_bytes_non_atomic(realname, ref+"\n",
249
create_parent_dir=True)
259
252
def remove_if_equals(self, name, old_ref):
285
278
if self.transport.has(".git/%s" % OBJECTDIR):
286
279
self.bare = False
287
280
self._controltransport = self.transport.clone('.git')
288
elif self.transport.has_any(["info/refs", OBJECTDIR, REFSDIR]):
281
elif self.transport.has(OBJECTDIR) or self.transport.has(REFSDIR):
290
283
self._controltransport = self.transport
324
317
return Index(self.index_path())
326
319
def has_index(self):
327
"""Check if an index is present."""
328
# Bare repos must never have index files; non-bare repos may have a
329
# missing index file, which is treated as empty.
320
return self._controltransport.has(INDEX_FILENAME)
332
322
def __repr__(self):
333
return "<%s for %r>" % (self.__class__.__name__, self.transport)
323
return "<TransportRepo for %r>" % self.transport
336
326
class TransportObjectStore(PackBasedObjectStore):
344
334
super(TransportObjectStore, self).__init__()
345
335
self.transport = transport
346
336
self.pack_transport = self.transport.clone(PACKDIR)
349
return "%s(%r)" % (self.__class__.__name__, self.transport)
351
338
def _pack_cache_stale(self):
352
339
return False # FIXME
376
363
size = self.pack_transport.stat(name).st_size
377
364
except TransportNotPossible:
378
# FIXME: This reads the whole pack file at once
379
f = self.pack_transport.get(name)
381
pd = PackData(name, StringIO(contents), size=len(contents))
366
# FIXME: This reads the whole pack file at once
367
f = self.pack_transport.get(name)
369
return PackData(name, StringIO(contents), size=len(contents))
383
pd = PackData(name, self.pack_transport.get(name),
371
pd = lambda: PackData(name, self.pack_transport.get(name),
385
373
idxname = name.replace(".pack", ".idx")
386
idx = load_pack_index_file(idxname, self.pack_transport.get(idxname))
387
pack = Pack.from_objects(pd, idx)
374
idx = lambda: load_pack_index_file(idxname, self.pack_transport.get(idxname))
375
pack = Pack.from_lazy_objects(pd, idx)
401
389
def _remove_loose_object(self, sha):
402
390
path = '%s/%s' % self._split_loose_object(sha)
403
self.transport.delete(path)
391
self.transport.remove(path)
405
393
def _get_loose_object(self, sha):
406
394
path = '%s/%s' % self._split_loose_object(sha)
438
426
basename = "pack-%s" % iter_sha1(entry[0] for entry in entries)
440
428
self.pack_transport.put_file(basename + ".pack", f)
441
idxfile = self.pack_transport.open_write_stream(basename + ".idx")
443
write_pack_index_v2(idxfile, entries, p.get_stored_checksum())
446
idxfile = self.pack_transport.get(basename + ".idx")
430
write_pack_index_v2(idxfile, entries, p.get_stored_checksum())
432
self.pack_transport.put_file(basename + ".idx", idxfile)
447
434
idx = load_pack_index_file(basename+".idx", idxfile)
448
435
final_pack = Pack.from_objects(p, idx)
449
436
self._add_known_pack(final_pack)
450
437
return final_pack
452
def add_thin_pack(self):
453
"""Add a new thin pack to this object store.
455
Thin packs are packs that contain deltas with parents that exist
458
from cStringIO import StringIO
461
if len(f.getvalue()) > 0:
462
return self.move_in_thin_pack(f)
467
def move_in_thin_pack(self, f):
468
"""Move a specific file containing a pack into the pack directory.
470
:note: The file should be on the same file system as the
473
:param path: Path to the pack file.
476
data = ThinPackData.from_file(self.get_raw, f, len(f.getvalue()))
477
idx = MemoryPackIndex(data.sorted_entries(), data.get_stored_checksum())
478
p = Pack.from_objects(data, idx)
480
pack_sha = idx.objects_sha1()
482
datafile = self.pack_transport.open_write_stream("pack-%s.pack" % pack_sha)
484
entries, data_sum = write_pack_data(datafile, ((o, None) for o in p.iterobjects()), len(p))
488
idxfile = self.pack_transport.open_write_stream("pack-%s.idx" % pack_sha)
490
write_pack_index_v2(idxfile, data.sorted_entries(), data_sum)
493
final_pack = Pack("pack-%s" % pack_sha)
494
self._add_known_pack(final_pack)
499
439
def add_pack(self):
500
440
"""Add a new pack to this object store.