diff options
author | Junio C Hamano <junkio@cox.net> | 2005-12-21 01:18:47 +0300 |
---|---|---|
committer | Junio C Hamano <junkio@cox.net> | 2005-12-21 01:18:47 +0300 |
commit | 4b3511b0f8422fd2c5b1b37c9655ae2ce904bca5 (patch) | |
tree | 823033e53c3caf6805f160bedea1075e464a0bdd | |
parent | 407c8eb0d09d4b84bbfda9e04895a35c8fd6fef6 (diff) |
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 <junkio@cox.net>
-rw-r--r-- | read-cache.c | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/read-cache.c b/read-cache.c index afdc2b075b..c5474d4975 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); } } |