瀏覽代碼

Refactor pack_refs logic from porcelain into refs module

Jelmer Vernooij 1 月之前
父節點
當前提交
b0f39a9b88
共有 3 個文件被更改,包括 36 次插入14 次删除
  1. 4 6
      dulwich/gc.py
  2. 1 8
      dulwich/porcelain.py
  3. 31 0
      dulwich/refs.py

+ 4 - 6
dulwich/gc.py

@@ -3,10 +3,10 @@
 import collections
 import time
 from dataclasses import dataclass, field
-from typing import Optional, Deque
+from typing import Optional
 
 from dulwich.object_store import BaseObjectStore, PackBasedObjectStore
-from dulwich.objects import Commit, Tag, Tree, ObjectID
+from dulwich.objects import Commit, ObjectID, Tag, Tree
 from dulwich.refs import RefsContainer
 
 
@@ -40,7 +40,7 @@ def find_reachable_objects(
         Set of reachable object SHAs
     """
     reachable = set()
-    pending: Deque[ObjectID] = collections.deque()
+    pending: collections.deque[ObjectID] = collections.deque()
 
     # Start with all refs
     for ref in refs_container.allkeys():
@@ -256,9 +256,7 @@ def garbage_collect(
     if progress:
         progress("Packing references")
     if not dry_run:
-        from dulwich.porcelain import pack_refs
-
-        pack_refs(repo)
+        repo.refs.pack_refs()
 
     # Delete loose unreachable objects
     if prune and not dry_run:

+ 1 - 8
dulwich/porcelain.py

@@ -402,14 +402,7 @@ def symbolic_ref(repo, ref_name, force=False) -> None:
 
 def pack_refs(repo, all=False) -> None:
     with open_repo_closing(repo) as repo_obj:
-        refs = repo_obj.refs
-        packed_refs = {
-            ref: refs[ref]
-            for ref in refs
-            if (all or ref.startswith(LOCAL_TAG_PREFIX)) and ref != b"HEAD"
-        }
-
-        refs.add_packed_refs(packed_refs)
+        repo_obj.refs.pack_refs(all=all)
 
 
 def commit(

+ 31 - 0
dulwich/refs.py

@@ -437,6 +437,14 @@ class RefsContainer:
                 ret[src] = dst
         return ret
 
+    def pack_refs(self, all: bool = False) -> None:
+        """Pack loose refs into packed-refs file.
+
+        Args:
+            all: If True, pack all refs. If False, only pack tags.
+        """
+        raise NotImplementedError(self.pack_refs)
+
 
 class DictRefsContainer(RefsContainer):
     """RefsContainer backed by a simple dict.
@@ -1054,6 +1062,29 @@ class DiskRefsContainer(RefsContainer):
 
         return True
 
+    def pack_refs(self, all: bool = False) -> None:
+        """Pack loose refs into packed-refs file.
+
+        Args:
+            all: If True, pack all refs. If False, only pack tags.
+        """
+        refs_to_pack: dict[Ref, Optional[ObjectID]] = {}
+        for ref in self.allkeys():
+            if ref == HEADREF:
+                # Never pack HEAD
+                continue
+            if all or ref.startswith(LOCAL_TAG_PREFIX):
+                try:
+                    sha = self[ref]
+                    if sha:
+                        refs_to_pack[ref] = sha
+                except KeyError:
+                    # Broken ref, skip it
+                    pass
+
+        if refs_to_pack:
+            self.add_packed_refs(refs_to_pack)
+
 
 def _split_ref_line(line):
     """Split a single ref line into a tuple of SHA1 and name."""