← Back to team overview

dulwich-users team mailing list archive

[PATCH 08/10] Delegate SHA peeling to the object store.

 

From: Dave Borowitz <dborowitz@xxxxxxxxxx>

Once a ref is resolved to a SHA, we no longer need access to the
RefsContainer, so the ObjectStore can do all the work.

Change-Id: I3e741e031d55b40be2631889989b8eddeff62997
---
 NEWS                               |    2 ++
 dulwich/object_store.py            |   16 ++++++++++++++++
 dulwich/repo.py                    |   11 +++--------
 dulwich/tests/test_object_store.py |   18 ++++++++++++++++++
 4 files changed, 39 insertions(+), 8 deletions(-)

diff --git a/NEWS b/NEWS
index e1fcfab..26c4fe4 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,8 @@
   * Distinguish between missing files and read errors in HTTP server.
     (Dave Borowitz)
 
+  * Delegate SHA peeling to the object store.  (Dave Borowitz)
+
  TESTS
 
   * Use GitFile when modifying packed-refs in tests. (Dave Borowitz)
diff --git a/dulwich/object_store.py b/dulwich/object_store.py
index c1716bd..0992e80 100644
--- a/dulwich/object_store.py
+++ b/dulwich/object_store.py
@@ -41,6 +41,7 @@ from dulwich.objects import (
     sha_to_hex,
     hex_to_filename,
     S_ISGITLINK,
+    object_class,
     )
 from dulwich.pack import (
     Pack,
@@ -243,6 +244,21 @@ class BaseObjectStore(object):
         """
         return self.iter_shas(self.find_missing_objects(have, want, progress))
 
+    def peel_sha(self, sha):
+        """Peel all tags from a SHA.
+
+        :param sha: The object SHA to peel.
+        :return: The fully-peeled SHA1 of a tag object, after peeling all
+            intermediate tags; if the original ref does not point to a tag, this
+            will equal the original SHA1.
+        """
+        obj = self[sha]
+        obj_class = object_class(obj.type_name)
+        while obj_class is Tag:
+            obj_class, sha = obj.object
+            obj = self[sha]
+        return obj
+
 
 class PackBasedObjectStore(BaseObjectStore):
 
diff --git a/dulwich/repo.py b/dulwich/repo.py
index 6b1d9d8..54a5546 100644
--- a/dulwich/repo.py
+++ b/dulwich/repo.py
@@ -938,20 +938,15 @@ class BaseRepo(object):
     def get_peeled(self, ref):
         """Get the peeled value of a ref.
 
-        :param ref: the refname to peel
-        :return: the fully-peeled SHA1 of a tag object, after peeling all
+        :param ref: The refname to peel.
+        :return: The fully-peeled SHA1 of a tag object, after peeling all
             intermediate tags; if the original ref does not point to a tag, this
             will equal the original SHA1.
         """
         cached = self.refs.get_peeled(ref)
         if cached is not None:
             return cached
-        obj = self[ref]
-        obj_class = object_class(obj.type_name)
-        while obj_class is Tag:
-            obj_class, sha = obj.object
-            obj = self.get_object(sha)
-        return obj.id
+        return self.object_store.peel_sha(self.refs[ref]).id
 
     def revision_history(self, head):
         """Returns a list of the commits reachable from head.
diff --git a/dulwich/tests/test_object_store.py b/dulwich/tests/test_object_store.py
index e34e75f..cc96df9 100644
--- a/dulwich/tests/test_object_store.py
+++ b/dulwich/tests/test_object_store.py
@@ -27,7 +27,9 @@ from dulwich.index import (
     commit_tree,
     )
 from dulwich.objects import (
+    object_class,
     Blob,
+    Tag,
     )
 from dulwich.object_store import (
     DiskObjectStore,
@@ -124,6 +126,22 @@ class ObjectStoreTests(object):
         actual = self.store.iter_tree_contents(tree_id, include_trees=True)
         self.assertEquals(expected, list(actual))
 
+    def make_tag(self, name, obj):
+        tag = make_object(Tag, name=name, message='',
+                          tag_time=12345, tag_timezone=0,
+                          tagger='Test Tagger <test@xxxxxxxxxxx>',
+                          object=(object_class(obj.type_name), obj.id))
+        self.store.add_object(tag)
+        return tag
+
+    def test_peel_sha(self):
+        self.store.add_object(testobject)
+        tag1 = self.make_tag('1', testobject)
+        tag2 = self.make_tag('2', testobject)
+        tag3 = self.make_tag('3', testobject)
+        for obj in [testobject, tag1, tag2, tag3]:
+            self.assertEqual(testobject, self.store.peel_sha(obj.id))
+
 
 class MemoryObjectStoreTests(ObjectStoreTests, TestCase):
 
-- 
1.7.1




References