84
90
iter_files = self.transport.clone(base).iter_files_recursive()
85
keys.update(("%s/%s" % (base, refname)).strip("/") for
91
keys.update(("%s/%s" % (base, urllib.unquote(refname))).strip("/") for
86
92
refname in iter_files if check_ref_format("%s/%s" % (base, refname)))
87
93
except (TransportNotPossible, NoSuchFile):
94
100
def allkeys(self):
96
if self.transport.has("HEAD"):
103
self.transport.get_bytes("HEAD")
99
109
iter_files = list(self.transport.clone("refs").iter_files_recursive())
100
110
for filename in iter_files:
101
refname = "refs/%s" % filename
111
refname = "refs/%s" % urllib.unquote(filename)
102
112
if check_ref_format(refname):
103
113
keys.add(refname)
104
114
except (TransportNotPossible, NoSuchFile):
276
287
self._remove_packed_ref(name)
290
def get(self, name, default=None):
280
297
class TransportRepo(BaseRepo):
282
def __init__(self, transport):
299
def __init__(self, transport, bare, refs_text=None):
283
300
self.transport = transport
285
if self.transport.has(".git/%s" % OBJECTDIR):
287
self._controltransport = self.transport.clone('.git')
288
elif self.transport.has_any(["info/refs", OBJECTDIR, REFSDIR]):
290
self._controltransport = self.transport
292
raise NotGitRepository(self.transport)
294
raise NotGitRepository(self.transport)
303
self._controltransport = self.transport
305
self._controltransport = self.transport.clone('.git')
295
306
object_store = TransportObjectStore(
296
307
self._controltransport.clone(OBJECTDIR))
308
if refs_text is not None:
309
from dulwich.repo import InfoRefsContainer # dulwich >= 0.8.2
310
refs_container = InfoRefsContainer(StringIO(refs_text))
312
head = TransportRefsContainer(self._controltransport).read_loose_ref("HEAD")
316
refs_container._refs["HEAD"] = head
318
refs_container = TransportRefsContainer(self._controltransport)
297
319
super(TransportRepo, self).__init__(object_store,
298
TransportRefsContainer(self._controltransport))
300
322
def get_named_file(self, path):
301
323
"""Get a file from the control dir with a specific name.
312
334
except NoSuchFile:
337
def _put_named_file(self, relpath, contents):
338
self._controltransport.put_bytes(relpath, contents)
315
340
def index_path(self):
316
341
"""Return the path to the index file."""
317
342
return self._controltransport.local_abspath(INDEX_FILENAME)
329
354
# missing index file, which is treated as empty.
330
355
return not self.bare
357
def get_config(self):
358
from dulwich.config import ConfigFile
360
return ConfigFile.from_file(self._controltransport.get('config'))
364
def get_config_stack(self):
365
from dulwich.config import StackedConfig
367
p = self.get_config()
373
backends.extend(StackedConfig.default_backends())
374
return StackedConfig(backends, writable=writable)
332
376
def __repr__(self):
333
377
return "<%s for %r>" % (self.__class__.__name__, self.transport)
380
def init(cls, transport, bare=False):
382
transport.mkdir(".git")
383
control_transport = transport.clone(".git")
385
control_transport = transport
386
for d in BASE_DIRECTORIES:
387
control_transport.mkdir("/".join(d))
388
control_transport.mkdir(OBJECTDIR)
389
TransportObjectStore.init(control_transport.clone(OBJECTDIR))
390
ret = cls(transport, bare)
391
ret.refs.set_symbolic_ref("HEAD", "refs/heads/master")
392
ret._init_files(bare)
336
396
class TransportObjectStore(PackBasedObjectStore):
337
397
"""Git-style object store that exists on disk."""
344
404
super(TransportObjectStore, self).__init__()
345
405
self.transport = transport
346
406
self.pack_transport = self.transport.clone(PACKDIR)
407
self._alternates = None
348
409
def __repr__(self):
349
410
return "%s(%r)" % (self.__class__.__name__, self.transport)
351
412
def _pack_cache_stale(self):
352
413
return False # FIXME
416
def alternates(self):
417
if self._alternates is not None:
418
return self._alternates
419
self._alternates = []
420
for path in self._read_alternate_paths():
422
t = _mod_transport.get_transport_from_path(path)
423
self._alternates.append(self.__class__(t))
424
return self._alternates
426
def _read_alternate_paths(self):
428
f = self.transport.get("info/alternates")
433
for l in f.read().splitlines():
354
443
def _pack_names(self):
356
445
f = self.transport.get('info/packs')
358
447
return self.pack_transport.list_dir(".")
361
for line in f.readlines():
362
line = line.rstrip("\n")
450
for line in f.read().splitlines():
365
453
(kind, name) = line.split(" ", 1)
473
561
:param path: Path to the pack file.
476
data = ThinPackData.from_file(self.get_raw, f, len(f.getvalue()))
564
data = PackData.from_file(self.get_raw, f, len(f.getvalue()))
477
565
idx = MemoryPackIndex(data.sorted_entries(), data.get_stored_checksum())
478
566
p = Pack.from_objects(data, idx)
480
568
pack_sha = idx.objects_sha1()
482
datafile = self.pack_transport.open_write_stream("pack-%s.pack" % pack_sha)
570
datafile = self.pack_transport.open_write_stream(
571
"pack-%s.pack" % pack_sha)
484
entries, data_sum = write_pack_data(datafile, ((o, None) for o in p.iterobjects()), len(p))
573
entries, data_sum = write_pack_data(datafile, p.pack_tuples())
488
idxfile = self.pack_transport.open_write_stream("pack-%s.idx" % pack_sha)
577
idxfile = self.pack_transport.open_write_stream(
578
"pack-%s.idx" % pack_sha)
490
580
write_pack_index_v2(idxfile, data.sorted_entries(), data_sum)