Selaa lähdekoodia

Handle race conditions with pack directory's mtime. Fixes #541

Jelmer Vernooij 7 vuotta sitten
vanhempi
commit
5ff68872bd
3 muutettua tiedostoa jossa 8 lisäystä ja 4 poistoa
  1. 3 0
      NEWS
  2. 4 3
      dulwich/object_store.py
  3. 1 1
      dulwich/tests/test_porcelain.py

+ 3 - 0
NEWS

@@ -28,6 +28,9 @@
   * Support treeish argument to porcelain.reset(), rather than
     requiring a ref/commit id. (Jelmer Vernooij)
 
+  * Handle race condition when mtime doesn't change between writes/reads.
+    (Jelmer Vernooij, #541)
+
  IMPROVEMENTS
 
   * Add basic support for reading ignore files in ``dulwich.ignore``.

+ 4 - 3
dulwich/object_store.py

@@ -22,7 +22,6 @@
 
 """Git object store interfaces and implementation."""
 
-
 from io import BytesIO
 import errno
 from itertools import chain
@@ -30,6 +29,7 @@ import os
 import stat
 import sys
 import tempfile
+import time
 
 from dulwich.diff_tree import (
     tree_changes,
@@ -481,7 +481,8 @@ class DiskObjectStore(PackBasedObjectStore):
                 self.close()
                 return
             raise
-        self._pack_cache_time = os.stat(self.pack_dir).st_mtime
+        self._pack_cache_time = max(
+                os.stat(self.pack_dir).st_mtime, time.time())
         pack_files = set()
         for name in pack_dir_contents:
             if name.startswith("pack-") and name.endswith(".pack"):
@@ -502,7 +503,7 @@ class DiskObjectStore(PackBasedObjectStore):
 
     def _pack_cache_stale(self):
         try:
-            return os.stat(self.pack_dir).st_mtime > self._pack_cache_time
+            return os.stat(self.pack_dir).st_mtime >= self._pack_cache_time
         except OSError as e:
             if e.errno == errno.ENOENT:
                 return True

+ 1 - 1
dulwich/tests/test_porcelain.py

@@ -620,7 +620,7 @@ class PushTests(PorcelainTestCase):
                 b'refs/heads/foo': r_clone[b'HEAD'].id,
                 b'refs/heads/master': new_id,
                 }, self.repo.get_refs())
-            self.assertEqual(r_clone[b'HEAD'].id, self.repo.refs[refs_path])
+            self.assertEqual(r_clone[b'HEAD'].id, self.repo[refs_path].id)
 
             # Get the change in the target repo corresponding to the add
             # this will be in the foo branch.