From 4b3511b0f8422fd2c5b1b37c9655ae2ce904bca5 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Tue, 20 Dec 2005 14:18:47 -0800 Subject: [PATCH] ce_smudge_racily_clean_entry: explain why it works. This is a tricky code and warrants extra commenting. I wasted 30 minutes trying to break it until I realized why it works. Signed-off-by: Junio C Hamano --- read-cache.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/read-cache.c b/read-cache.c index afdc2b07..c5474d49 100644 --- a/read-cache.c +++ b/read-cache.c @@ -616,7 +616,31 @@ static void ce_smudge_racily_clean_entry(struct cache_entry *ce) if (ce_match_stat_basic(ce, &st)) return; if (ce_modified_check_fs(ce, &st)) { - /* This is "racily clean"; smudge it */ + /* This is "racily clean"; smudge it. Note that this + * is a tricky code. At first glance, it may appear + * that it can break with this sequence: + * + * $ echo xyzzy >frotz + * $ git-update-index --add frotz + * $ : >frotz + * $ sleep 3 + * $ echo filfre >nitfol + * $ git-update-index --add nitfol + * + * but it does not. Whe the second update-index runs, + * it notices that the entry "frotz" has the same timestamp + * as index, and if we were to smudge it by resetting its + * size to zero here, then the object name recorded + * in index is the 6-byte file but the cached stat information + * becomes zero --- which would then match what we would + * obtain from the filesystem next time we stat("frotz"). + * + * However, the second update-index, before calling + * this function, notices that the cached size is 6 + * bytes and what is on the filesystem is an empty + * file, and never calls us, so the cached size information + * for "frotz" stays 6 which does not match the filesystem. + */ ce->ce_size = htonl(0); } } -- 2.11.0