aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-06-10 10:44:43 -0700
committerJunio C Hamano <gitster@pobox.com>2008-06-19 14:14:45 -0700
commitf49c2c22fef520fd69ff26869c26dc58a834de2c (patch)
tree56845e698524d15a6a51bcc1a83295059c376be8
parent4afbcab9898ce63ad641dd0de6e9b69deda44330 (diff)
downloadgit-f49c2c22fef520fd69ff26869c26dc58a834de2c.tar.gz
git-f49c2c22fef520fd69ff26869c26dc58a834de2c.tar.xz
racy-git: an empty blob has a fixed object name
We use size=0 as the magic token to say the entry is known to be racily clean, but a sequence that does: - update the path with a non-empty blob and write the index; - update an unrelated path and write the index -- this smudges the above entry; - truncate the path to size zero. would make both the size field for the path in the index and the size on the filesystem zero. We should not mistake it as a clean index entry. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--read-cache.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/read-cache.c b/read-cache.c
index a92b25b59..6fa3c2114 100644
--- a/read-cache.c
+++ b/read-cache.c
@@ -197,6 +197,16 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st)
return 0;
}
+static int is_empty_blob_sha1(const unsigned char *sha1)
+{
+ static const unsigned char empty_blob_sha1[20] = {
+ 0xe6,0x9d,0xe2,0x9b,0xb2,0xd1,0xd6,0x43,0x4b,0x8b,
+ 0x29,0xae,0x77,0x5a,0xd8,0xc2,0xe4,0x8c,0x53,0x91
+ };
+
+ return !hashcmp(sha1, empty_blob_sha1);
+}
+
static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
{
unsigned int changed = 0;
@@ -252,6 +262,12 @@ static int ce_match_stat_basic(struct cache_entry *ce, struct stat *st)
if (ce->ce_size != (unsigned int) st->st_size)
changed |= DATA_CHANGED;
+ /* Racily smudged entry? */
+ if (!ce->ce_size) {
+ if (!is_empty_blob_sha1(ce->sha1))
+ changed |= DATA_CHANGED;
+ }
+
return changed;
}