Skip to content

Commit

Permalink
read-cache: fix reading of split index
Browse files Browse the repository at this point in the history
The split index extension uses ewah bitmaps to mark index entries as
deleted, instead of removing them from the index directly.  This can
result in an on-disk index, in which entries of stage #0 and higher
stages appear, which are removed later when the index bases are merged.

15999d0 read_index_from(): catch out of order entries when reading an
index file introduces a check which checks if the entries are in order
after each index entry is read in do_read_index.  This check may however
fail when a split index is read.

Fix this by moving checking the index after we know there is no split
index or after the split index bases are successfully merged instead.

Signed-off-by: Thomas Gummerer <t.gummerer@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
Thomas Gummerer authored and Junio C Hamano committed Mar 20, 2015
1 parent 9874fca commit 03f15a7
Showing 1 changed file with 23 additions and 19 deletions.
42 changes: 23 additions & 19 deletions read-cache.c
Original file line number Diff line number Diff line change
Expand Up @@ -1480,18 +1480,25 @@ static struct cache_entry *create_from_disk(struct ondisk_cache_entry *ondisk,
return ce;
}

static void check_ce_order(struct cache_entry *ce, struct cache_entry *next_ce)
{
int name_compare = strcmp(ce->name, next_ce->name);
if (0 < name_compare)
die("unordered stage entries in index");
if (!name_compare) {
if (!ce_stage(ce))
die("multiple stage entries for merged file '%s'",
ce->name);
if (ce_stage(ce) > ce_stage(next_ce))
die("unordered stage entries for '%s'",
ce->name);
static void check_ce_order(struct index_state *istate)
{
unsigned int i;

for (i = 1; i < istate->cache_nr; i++) {
struct cache_entry *ce = istate->cache[i - 1];
struct cache_entry *next_ce = istate->cache[i];
int name_compare = strcmp(ce->name, next_ce->name);

if (0 < name_compare)
die("unordered stage entries in index");
if (!name_compare) {
if (!ce_stage(ce))
die("multiple stage entries for merged file '%s'",
ce->name);
if (ce_stage(ce) > ce_stage(next_ce))
die("unordered stage entries for '%s'",
ce->name);
}
}
}

Expand Down Expand Up @@ -1556,9 +1563,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist)
ce = create_from_disk(disk_ce, &consumed, previous_name);
set_index_entry(istate, i, ce);

if (i > 0)
check_ce_order(istate->cache[i - 1], ce);

src_offset += consumed;
}
strbuf_release(&previous_name_buf);
Expand Down Expand Up @@ -1602,11 +1606,10 @@ int read_index_from(struct index_state *istate, const char *path)

ret = do_read_index(istate, path, 0);
split_index = istate->split_index;
if (!split_index)
return ret;

if (is_null_sha1(split_index->base_sha1))
if (!split_index || is_null_sha1(split_index->base_sha1)) {
check_ce_order(istate);
return ret;
}

if (split_index->base)
discard_index(split_index->base);
Expand All @@ -1622,6 +1625,7 @@ int read_index_from(struct index_state *istate, const char *path)
sha1_to_hex(split_index->base_sha1)),
sha1_to_hex(split_index->base->sha1));
merge_base_index(istate);
check_ce_order(istate);
return ret;
}

Expand Down

0 comments on commit 03f15a7

Please sign in to comment.