commit d7fe585dc377b48869e7beabc3c226f4e1ce7012 from: Jelmer Vernooij date: Tue Jan 17 19:17:21 2023 UTC Factor out serialize_refs. commit - beb8f959f7e4e80360854f0969331b48974ff386 commit + d7fe585dc377b48869e7beabc3c226f4e1ce7012 blob - 6a9baac77f06b53c286baa5b450324ddfdd6dcfc blob + 8d9b70351637dabed4e9545e0aae95cff2faa33d --- dulwich/object_store.py +++ dulwich/object_store.py @@ -277,7 +277,7 @@ class BaseObjectStore: warnings.warn( "Please use dulwich.object_store.peel_sha()", DeprecationWarning, stacklevel=2) - return peel_sha(self, sha) + return peel_sha(self, sha)[1] def _get_depth( self, head, get_parents=lambda commit: commit.parents, max_depth=None, @@ -1642,7 +1642,7 @@ def iter_tree_contents( yield entry -def peel_sha(store: ObjectContainer, sha: bytes) -> ShaFile: +def peel_sha(store: ObjectContainer, sha: bytes) -> Tuple[ShaFile, ShaFile]: """Peel all tags from a SHA. Args: @@ -1651,10 +1651,10 @@ def peel_sha(store: ObjectContainer, sha: bytes) -> Sh intermediate tags; if the original ref does not point to a tag, this will equal the original SHA1. """ - obj = store[sha] + unpeeled = obj = store[sha] obj_class = object_class(obj.type_name) while obj_class is Tag: assert isinstance(obj, Tag) obj_class, sha = obj.object obj = store[sha] - return obj + return unpeeled, obj blob - b2322a04fe90cb9954eb03a8e03b56bdc5577c59 blob + 1fc178af8699bbec8acab64786a05c1d2d6e3244 --- dulwich/refs.py +++ dulwich/refs.py @@ -25,6 +25,7 @@ from contextlib import suppress import os from typing import Dict, Optional +import warnings from dulwich.errors import ( PackedRefsException, @@ -1156,7 +1157,7 @@ def read_info_refs(f): def write_info_refs(refs, store: ObjectContainer): """Generate info refs.""" - # Avoid recursive import :( + # TODO: Avoid recursive import :( from dulwich.object_store import peel_sha for name, sha in sorted(refs.items()): # get_refs() includes HEAD as a special case, but we don't want to @@ -1167,7 +1168,7 @@ def write_info_refs(refs, store: ObjectContainer): o = store[sha] except KeyError: continue - peeled = peel_sha(store, sha) + unpeeled, peeled = peel_sha(store, sha) yield o.id + b"\t" + name + b"\n" if o.id != peeled.id: yield peeled.id + b"\t" + name + PEELED_TAG_SUFFIX + b"\n" @@ -1281,3 +1282,24 @@ def _import_remote_refs( if n.startswith(LOCAL_TAG_PREFIX) and not n.endswith(PEELED_TAG_SUFFIX) } refs_container.import_refs(LOCAL_TAG_PREFIX, tags, message=message, prune=prune_tags) + + +def serialize_refs(store, refs): + # TODO: Avoid recursive import :( + from dulwich.object_store import peel_sha + ret = {} + for ref, sha in refs.items(): + try: + unpeeled, peeled = peel_sha(store, sha) + except KeyError: + warnings.warn( + "ref %s points at non-present sha %s" + % (ref.decode("utf-8", "replace"), sha.decode("ascii")), + UserWarning, + ) + continue + else: + if isinstance(unpeeled, Tag): + ret[ref + PEELED_TAG_SUFFIX] = peeled.id + ret[ref] = unpeeled.id + return ret blob - 0c65477af374c2cd9261805d2ad59f04d763b690 blob + e3faf8d12db1cc30b0f449743335830d599a1bc3 --- dulwich/repo.py +++ dulwich/repo.py @@ -46,7 +46,9 @@ from typing import ( Iterable, Set ) +import warnings + if TYPE_CHECKING: # There are no circular imports here, but we try to defer imports as long # as possible to reduce start-up time for anything that doesn't need @@ -105,6 +107,7 @@ from dulwich.refs import ( # noqa: F401 ANNOTATED_TAG_SUFFIX, LOCAL_BRANCH_PREFIX, LOCAL_TAG_PREFIX, + serialize_refs, check_ref_format, RefsContainer, DictRefsContainer, @@ -118,9 +121,6 @@ from dulwich.refs import ( # noqa: F401 _set_head, _set_origin_head, ) - - -import warnings CONTROLDIR = ".git" @@ -520,21 +520,7 @@ class BaseRepo: if depth not in (None, 0): raise NotImplementedError("depth not supported yet") - refs = {} - for ref, sha in self.get_refs().items(): - try: - obj = self.object_store[sha] - except KeyError: - warnings.warn( - "ref %s points at non-present sha %s" - % (ref.decode("utf-8", "replace"), sha.decode("ascii")), - UserWarning, - ) - continue - else: - if isinstance(obj, Tag): - refs[ref + PEELED_TAG_SUFFIX] = obj.object[1] - refs[ref] = sha + refs = serialize_refs(self.object_store, self.get_refs()) wants = determine_wants(refs) if not isinstance(wants, list): @@ -772,7 +758,7 @@ class BaseRepo: cached = self.refs.get_peeled(ref) if cached is not None: return cached - return peel_sha(self.object_store, self.refs[ref]).id + return peel_sha(self.object_store, self.refs[ref])[1].id def get_walker(self, include: Optional[List[bytes]] = None, *args, **kwargs): blob - 95f570dc709461390beffcd545c4379d5fb0e25b blob + b97d33048f27a3d47af4b0d3edae818b1534211e --- dulwich/server.py +++ dulwich/server.py @@ -499,9 +499,9 @@ def _find_shallow(store: ObjectContainer, heads, depth todo = [] # stack of (sha, depth) for head_sha in heads: - obj = peel_sha(store, head_sha) - if isinstance(obj, Commit): - todo.append((obj.id, 1)) + _unpeeled, peeled = peel_sha(store, head_sha) + if isinstance(peeled, Commit): + todo.append((peeled.id, 1)) not_shallow = set() shallow = set() blob - c03a11956bdd8f3a1c4abc67ae7c3fecdc52bd81 blob + 54b4f5d3f64b4f3f078e5a4404f6c0e504b44970 --- dulwich/tests/test_object_store.py +++ dulwich/tests/test_object_store.py @@ -264,7 +264,7 @@ class ObjectStoreTests: tag2 = self.make_tag(b"2", testobject) tag3 = self.make_tag(b"3", testobject) for obj in [testobject, tag1, tag2, tag3]: - self.assertEqual(testobject, peel_sha(self.store, obj.id)) + self.assertEqual((obj, testobject), peel_sha(self.store, obj.id)) def test_get_raw(self): self.store.add_object(testobject)