Skip to content

Commit 207ad3c

Browse files
committed
Merge branch 'sc/pack-refs-deletion-racefix'
"git pack-refs" can lose refs that are created while running, which is getting corrected. * sc/pack-refs-deletion-racefix: pack-refs: always refresh after taking the lock file
2 parents 77067b6 + a613d4f commit 207ad3c

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

refs/packed-backend.c

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,14 +1012,23 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err)
10121012
}
10131013

10141014
/*
1015-
* Now that we hold the `packed-refs` lock, make sure that our
1016-
* snapshot matches the current version of the file. Normally
1017-
* `get_snapshot()` does that for us, but that function
1018-
* assumes that when the file is locked, any existing snapshot
1019-
* is still valid. We've just locked the file, but it might
1020-
* have changed the moment *before* we locked it.
1015+
* There is a stat-validity problem might cause `update-ref -d`
1016+
* lost the newly commit of a ref, because a new `packed-refs`
1017+
* file might has the same on-disk file attributes such as
1018+
* timestamp, file size and inode value, but has a changed
1019+
* ref value.
1020+
*
1021+
* This could happen with a very small chance when
1022+
* `update-ref -d` is called and at the same time another
1023+
* `pack-refs --all` process is running.
1024+
*
1025+
* Now that we hold the `packed-refs` lock, it is important
1026+
* to make sure we could read the latest version of
1027+
* `packed-refs` file no matter we have just mmap it or not.
1028+
* So what need to do is clear the snapshot if we hold it
1029+
* already.
10211030
*/
1022-
validate_snapshot(refs);
1031+
clear_snapshot(refs);
10231032

10241033
/*
10251034
* Now make sure that the packed-refs file as it exists in the

0 commit comments

Comments
 (0)