Skip to content

Commit

Permalink
racy-git: an empty blob has a fixed object name
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Linus Torvalds authored and Junio C Hamano committed Jun 19, 2008
1 parent 4afbcab commit f49c2c2
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit f49c2c2

Please sign in to comment.