Merge branch 'jp/index-with-corrupt-stages'

A broken reimplementation of Git could write an invalid index that
records both stage #0 and higher stage entries for the same path.
Notice and reject such an index, as there is no sensible fallback
(we do not know if the broken tool wanted to resolve and forgot to
remove higher stage entries, or if it wanted to unresolve and
forgot to remove the stage#0 entry).

* jp/index-with-corrupt-stages:
  read_index_unmerged(): remove unnecessary loop index adjustment
  read_index_from(): catch out of order entries when reading an index file
This commit is contained in:
Junio C Hamano 2014-09-19 11:38:34 -07:00
Родитель bd656f6e7b 0344d93ced
Коммит 04631848c4
1 изменённых файлов: 18 добавлений и 1 удалений

Просмотреть файл

@ -1465,6 +1465,21 @@ 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);
}
}
/* remember to discard_cache() before reading a different cache! */
int do_read_index(struct index_state *istate, const char *path, int must_exist)
{
@ -1526,6 +1541,9 @@ 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);
@ -2172,7 +2190,6 @@ int read_index_unmerged(struct index_state *istate)
if (add_index_entry(istate, new_ce, 0))
return error("%s: cannot drop to stage #0",
new_ce->name);
i = index_name_pos(istate, new_ce->name, len);
}
return unmerged;
}