Browse Source

Only return files from the loose store that look like git objects

In some situations (e.g. a git crash), one can end up with temporary files in
the git loose object store. These temporary files pollute dulwich's loose object
iterator.
Nicolas Dandrimont 4 years ago
parent
commit
f268cf2649
3 changed files with 24 additions and 1 deletions
  1. 3 0
      NEWS
  2. 5 1
      dulwich/object_store.py
  3. 16 0
      dulwich/tests/test_object_store.py

+ 3 - 0
NEWS

@@ -2,6 +2,9 @@
 
  * Drop support for Python 2. (Jelmer Vernooij)
 
+ * Only return files from the loose store that look like git objects.
+   (Nicolas Dandrimont)
+
 0.19.17	UNRELEASED
 
  * Don't break when encountering block devices.

+ 5 - 1
dulwich/object_store.py

@@ -47,6 +47,7 @@ from dulwich.objects import (
     hex_to_filename,
     S_ISGITLINK,
     object_class,
+    valid_hexsha,
     )
 from dulwich.pack import (
     Pack,
@@ -644,7 +645,10 @@ class DiskObjectStore(PackBasedObjectStore):
             if len(base) != 2:
                 continue
             for rest in os.listdir(os.path.join(self.path, base)):
-                yield os.fsencode(base+rest)
+                sha = os.fsencode(base+rest)
+                if not valid_hexsha(sha):
+                    continue
+                yield sha
 
     def _get_loose_object(self, sha):
         path = self._get_shafile_path(sha)

+ 16 - 0
dulwich/tests/test_object_store.py

@@ -389,6 +389,22 @@ class DiskObjectStoreTests(PackBasedObjectStoreTests, TestCase):
         self.assertEqual([testobject.id],
                          list(self.store._iter_loose_objects()))
 
+    def test_tempfile_in_loose_store(self):
+        self.store.add_object(testobject)
+        self.assertEqual([testobject.id],
+                         list(self.store._iter_loose_objects()))
+
+        # add temporary files to the loose store
+        for i in range(256):
+            dirname = os.path.join(self.store_dir, "%02x" % i)
+            if not os.path.isdir(dirname):
+                os.makedirs(dirname)
+            fd, n = tempfile.mkstemp(prefix="tmp_obj_", dir=dirname)
+            os.close(fd)
+
+        self.assertEqual([testobject.id],
+                         list(self.store._iter_loose_objects()))
+
     def test_add_alternate_path(self):
         store = DiskObjectStore(self.store_dir)
         self.assertEqual([], list(store._read_alternate_paths()))