about summary refs log tree commit diff
path: root/third_party/git/refs
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/git/refs')
-rw-r--r--third_party/git/refs/files-backend.c7
-rw-r--r--third_party/git/refs/packed-backend.c23
-rw-r--r--third_party/git/refs/refs-internal.h2
3 files changed, 12 insertions, 20 deletions
diff --git a/third_party/git/refs/files-backend.c b/third_party/git/refs/files-backend.c
index 561c33ac8a97..d60767ab739f 100644
--- a/third_party/git/refs/files-backend.c
+++ b/third_party/git/refs/files-backend.c
@@ -465,7 +465,8 @@ stat_ref:
 	close(fd);
 	strbuf_rtrim(&sb_contents);
 	buf = sb_contents.buf;
-	if (skip_prefix(buf, "ref:", &buf)) {
+	if (starts_with(buf, "ref:")) {
+		buf += 4;
 		while (isspace(*buf))
 			buf++;
 
@@ -1326,7 +1327,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
 {
 	struct files_ref_store *refs =
 		files_downcast(ref_store, REF_STORE_WRITE, "rename_ref");
-	struct object_id orig_oid;
+	struct object_id oid, orig_oid;
 	int flag = 0, logmoved = 0;
 	struct ref_lock *lock;
 	struct stat loginfo;
@@ -1394,7 +1395,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
 	 */
 	if (!copy && !refs_read_ref_full(&refs->base, newrefname,
 				RESOLVE_REF_READING | RESOLVE_REF_NO_RECURSE,
-				NULL, NULL) &&
+				&oid, NULL) &&
 	    refs_delete_ref(&refs->base, NULL, newrefname,
 			    NULL, REF_NO_DEREF)) {
 		if (errno == EISDIR) {
diff --git a/third_party/git/refs/packed-backend.c b/third_party/git/refs/packed-backend.c
index 4458a0f69ccb..c01c7f5901a6 100644
--- a/third_party/git/refs/packed-backend.c
+++ b/third_party/git/refs/packed-backend.c
@@ -1012,23 +1012,14 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
 	}
 
 	/*
-	 * 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.
+	 * 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.
 	 */
-	clear_snapshot(refs);
+	validate_snapshot(refs);
 
 	/*
 	 * Now make sure that the packed-refs file as it exists in the
diff --git a/third_party/git/refs/refs-internal.h b/third_party/git/refs/refs-internal.h
index ff2436c0fb70..f2d8c0123a77 100644
--- a/third_party/git/refs/refs-internal.h
+++ b/third_party/git/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
- * associated with the iteration, frees the ref_iterator object, and
+ * assocated 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