summaryrefslogtreecommitdiff
path: root/refs
diff options
context:
space:
mode:
Diffstat (limited to 'refs')
-rw-r--r--refs/packed-backend.c23
-rw-r--r--refs/refs-internal.h2
2 files changed, 17 insertions, 8 deletions
diff --git a/refs/packed-backend.c b/refs/packed-backend.c
index c01c7f5901..4458a0f69c 100644
--- a/refs/packed-backend.c
+++ b/refs/packed-backend.c
@@ -1012,14 +1012,23 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
}
/*
- * Now that we hold the `packed-refs` lock, make sure that our
- * snapshot matches the current version of the file. Normally
- * `get_snapshot()` does that for us, but that function
- * assumes that when the file is locked, any existing snapshot
- * is still valid. We've just locked the file, but it might
- * have changed the moment *before* we locked it.
+ * There is a stat-validity problem might cause `update-ref -d`
+ * lost the newly commit of a ref, because a new `packed-refs`
+ * file might has the same on-disk file attributes such as
+ * timestamp, file size and inode value, but has a changed
+ * ref value.
+ *
+ * This could happen with a very small chance when
+ * `update-ref -d` is called and at the same time another
+ * `pack-refs --all` process is running.
+ *
+ * Now that we hold the `packed-refs` lock, it is important
+ * to make sure we could read the latest version of
+ * `packed-refs` file no matter we have just mmap it or not.
+ * So what need to do is clear the snapshot if we hold it
+ * already.
*/
- validate_snapshot(refs);
+ clear_snapshot(refs);
/*
* Now make sure that the packed-refs file as it exists in the
diff --git a/refs/refs-internal.h b/refs/refs-internal.h
index f2d8c0123a..ff2436c0fb 100644
--- a/refs/refs-internal.h
+++ b/refs/refs-internal.h
@@ -262,7 +262,7 @@ int refs_rename_ref_available(struct ref_store *refs,
* after calling ref_iterator_advance() again or calling
* ref_iterator_abort(), you must make a copy. When the iteration has
* been exhausted, ref_iterator_advance() releases any resources
- * assocated with the iteration, frees the ref_iterator object, and
+ * associated with the iteration, frees the ref_iterator object, and
* returns ITER_DONE. If you want to abort the iteration early, call
* ref_iterator_abort(), which also frees the ref_iterator object and
* any associated resources. If there was an internal error advancing