Handle race conditions with pack directory's mtime. Fixes #541
authorJelmer Vernooij <jelmer@jelmer.uk>
Fri, 28 Jul 2017 00:40:14 +0000 (00:40 +0000)
committerJelmer Vernooij <jelmer@jelmer.uk>
Fri, 28 Jul 2017 01:06:17 +0000 (01:06 +0000)
NEWS
dulwich/object_store.py
dulwich/tests/test_porcelain.py

diff --git a/NEWS b/NEWS
index ec0a30a6ba5dab17bb0f89c52c62fd9cf19b51f4..55a3c1ab44363b24b9c2dac40b4414ad48f1f357 100644 (file)
--- a/NEWS
+++ b/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``.
index fc717c2a3f0be9731ba60d40869346512bbc99e2..1144cba151b8f5d2f80520b1d507d600fe090731 100644 (file)
@@ -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
index 8611f7af3a40271118072dbf50230a66c70706d3..4e9ea28af3cbb5438565d4e6dea95569ca584d31 100644 (file)
@@ -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.