ce_smudge_racily_clean_entry: explain why it works.
authorJunio C Hamano <junkio@cox.net>
Tue, 20 Dec 2005 22:18:47 +0000 (14:18 -0800)
committerJunio C Hamano <junkio@cox.net>
Tue, 20 Dec 2005 22:18:47 +0000 (14:18 -0800)
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>
read-cache.c

index afdc2b0..c5474d4 100644 (file)
@@ -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);
        }
 }