182
177
"""Return the cached peeled value of a ref, if available.
184
179
:param name: Name of the ref to peel
185
:return: The peeled value of the ref. If the ref is known not point to a
186
tag, this will be the SHA the ref refers to. If the ref may point to
187
a tag, but no cached information is available, None is returned.
180
:return: The peeled value of the ref. If the ref is known not point to
181
a tag, this will be the SHA the ref refers to. If the ref may point
182
to a tag, but no cached information is available, None is returned.
189
184
self.get_packed_refs()
190
185
if self._peeled_refs is None or name not in self._packed_refs:
359
356
self._ensure_dir_exists(urlutils.quote_from_bytes(name))
360
357
lockname = urlutils.quote_from_bytes(name + b".lock")
362
local_path = self.transport.local_abspath(urlutils.quote_from_bytes(name))
359
local_path = transport.local_abspath(
360
urlutils.quote_from_bytes(name))
363
361
except NotLocalUrl:
364
362
# This is racy, but what can we do?
365
if self.transport.has(lockname):
363
if transport.has(lockname):
366
364
raise LockContention(name)
367
lock_result = self.transport.put_bytes(lockname, b'Locked by brz-git')
368
return LogicalLockResult(lambda: self.transport.delete(lockname))
365
transport.put_bytes(lockname, b'Locked by brz-git')
366
return LogicalLockResult(lambda: transport.delete(lockname))
371
369
gf = GitFile(local_path, 'wb')
429
429
if refs_text is not None:
430
430
refs_container = InfoRefsContainer(BytesIO(refs_text))
432
head = TransportRefsContainer(self._commontransport).read_loose_ref("HEAD")
432
head = TransportRefsContainer(
433
self._commontransport).read_loose_ref("HEAD")
436
437
refs_container._refs["HEAD"] = head
438
439
refs_container = TransportRefsContainer(
439
self._commontransport, self._controltransport)
440
self._commontransport, self._controltransport)
440
441
super(TransportRepo, self).__init__(object_store,
443
444
def controldir(self):
444
445
return self._controltransport.local_abspath('.')
592
# FIXME: Never invalidates.
593
if not self._pack_cache:
594
self._update_pack_cache()
595
return self._pack_cache.values()
597
591
def _update_pack_cache(self):
598
for pack in self._load_packs():
599
self._pack_cache[pack._basename] = pack
593
pack_dir_contents = self._pack_names()
594
for name in pack_dir_contents:
595
if name.startswith("pack-") and name.endswith(".pack"):
596
# verify that idx exists first (otherwise the pack was not yet
598
idx_name = os.path.splitext(name)[0] + ".idx"
599
if idx_name in pack_dir_contents:
600
pack_files.add(os.path.splitext(name)[0])
603
for basename in pack_files:
604
pack_name = basename + ".pack"
605
if basename not in self._pack_cache:
607
size = self.pack_transport.stat(pack_name).st_size
608
except TransportNotPossible:
609
f = self.pack_transport.get(pack_name)
610
pd = PackData(pack_name, f)
613
pack_name, self.pack_transport.get(pack_name),
615
idxname = basename + ".idx"
616
idx = load_pack_index_file(
617
idxname, self.pack_transport.get(idxname))
618
pack = Pack.from_objects(pd, idx)
619
pack._basename = basename
620
self._pack_cache[basename] = pack
621
new_packs.append(pack)
622
# Remove disappeared pack files
623
for f in set(self._pack_cache) - pack_files:
624
self._pack_cache.pop(f).close()
601
627
def _pack_names(self):
603
f = self.transport.get('info/packs')
605
629
return self.pack_transport.list_dir(".")
609
for line in f.read().splitlines():
612
(kind, name) = line.split(b" ", 1)
630
except TransportNotPossible:
632
f = self.transport.get('info/packs')
634
# Hmm, warn about running 'git update-server-info' ?
638
return read_packs_file(f)
618
642
def _remove_pack(self, pack):
619
643
self.pack_transport.delete(os.path.basename(pack.index.path))
620
644
self.pack_transport.delete(pack.data.filename)
622
def _load_packs(self):
624
for name in self._pack_names():
625
if name.startswith("pack-") and name.endswith(".pack"):
627
size = self.pack_transport.stat(name).st_size
628
except TransportNotPossible:
629
f = self.pack_transport.get(name)
630
pd = PackData(name, f, size=len(contents))
632
pd = PackData(name, self.pack_transport.get(name),
634
idxname = name.replace(".pack", ".idx")
635
idx = load_pack_index_file(idxname, self.pack_transport.get(idxname))
636
pack = Pack.from_objects(pd, idx)
637
pack._basename = idxname[:-4]
646
del self._pack_cache[os.path.basename(pack._basename)]
641
650
def _iter_loose_objects(self):
642
651
for base in self.transport.list_dir('.'):
643
652
if len(base) != 2:
645
654
for rest in self.transport.list_dir(base):
646
yield (base+rest).encode(sys.getfilesystemencoding())
655
yield (base + rest).encode(sys.getfilesystemencoding())
648
657
def _split_loose_object(self, sha):
649
658
return (sha[:2], sha[2:])
698
708
idxfile = self.pack_transport.get(basename + ".idx")
699
idx = load_pack_index_file(basename+".idx", idxfile)
709
idx = load_pack_index_file(basename + ".idx", idxfile)
700
710
final_pack = Pack.from_objects(p, idx)
701
711
final_pack._basename = basename
702
self._add_known_pack(basename, final_pack)
712
self._add_cached_pack(basename, final_pack)
703
713
return final_pack
705
715
def move_in_thin_pack(self, f):
714
724
p = Pack('', resolve_ext_ref=self.get_raw)
715
725
p._data = PackData.from_file(f, len(f.getvalue()))
717
p._idx_load = lambda: MemoryPackIndex(p.data.sorted_entries(), p.data.get_stored_checksum())
727
p._idx_load = lambda: MemoryPackIndex(
728
p.data.sorted_entries(), p.data.get_stored_checksum())
719
730
pack_sha = p.index.objects_sha1()
721
732
datafile = self.pack_transport.open_write_stream(
722
"pack-%s.pack" % pack_sha.decode('ascii'))
733
"pack-%s.pack" % pack_sha.decode('ascii'))
724
735
entries, data_sum = write_pack_objects(datafile, p.pack_tuples())