On Sun, Sep 02, 2018 at 12:17:53AM +0200, Ævar Arnfjörð Bjarmason wrote: > > Here are the steps to reproduce it: > > $ git clone git://github.com/lucvoo/sparse-dev.git <somedir> > > $ cd <somedir> > > $ git co index-corruption > > $ git rm -r validation/ Documentation/ > > $ git commit -m <some message> -p > > $ git status > > error: index uses $?+? extension, which we do not understand > > fatal: index file corrupt > > > > The 'extension' pattern '$?+?', can vary a bit, sometimes > > it's just '????', but always seems 4 chars. > > If the commit command doesn't use the '-p' flag, there is no > > problem. The repository itself is not corrupted, it's only > > the index. It happends with git 2.18.0 and 2.17.0 > > Yeah this is a bug, I didn't dig much but testing with this script down > to 2.8.0: > [...] > I found that the first bad commit was: 680ee550d7 ("commit: skip > discarding the index if there is no pre-commit hook", 2017-08-14) I think it's much older than that. I set up my test repo like this: git clone git://github.com/lucvoo/sparse-dev.git cd sparse-dev git checkout --detach and then bisected with this script: cd /path/to/sparse-dev rm .git/index git reset --hard index-corruption && git rm -q -r validation/ Documentation/ && git commit -qm foo -p && git status Since a33fc72fe9 (read-cache: force_verify_index_checksum, 2017-04-14), that produces the corrupt extension error. But before that, I consistently get: error: bad index file sha1 signature fatal: index file corrupt from git-commit. And that bisects back to 9c4d6c0297 (cache-tree: Write updated cache-tree after commit, 2014-07-13). If I revert that commit (which takes some untangling, see below), then the problem seems to go away. Here's the patch I tried on top of the current master, though I think it is actually the first hunk that is making the difference. --- diff --git a/builtin/commit.c b/builtin/commit.c index 0d9828e29e..779c5e2cb5 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -359,13 +359,6 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix discard_cache(); read_cache_from(get_lock_file_path(&index_lock)); - if (update_main_cache_tree(WRITE_TREE_SILENT) == 0) { - if (reopen_lock_file(&index_lock) < 0) - die(_("unable to write index file")); - if (write_locked_index(&the_index, &index_lock, 0)) - die(_("unable to update temporary index")); - } else - warning(_("Failed to update main cache tree")); commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); @@ -408,9 +401,6 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix if (!only && !pathspec.nr) { hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); refresh_cache_or_die(refresh_flags); - if (active_cache_changed - || !cache_tree_fully_valid(active_cache_tree)) - update_main_cache_tree(WRITE_TREE_SILENT); if (write_locked_index(&the_index, &index_lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write new_index file")); @@ -457,7 +447,6 @@ static const char *prepare_index(int argc, const char **argv, const char *prefix hold_locked_index(&index_lock, LOCK_DIE_ON_ERROR); add_remove_files(&partial); refresh_cache(REFRESH_QUIET); - update_main_cache_tree(WRITE_TREE_SILENT); if (write_locked_index(&the_index, &index_lock, 0)) die(_("unable to write new_index file")); -Peff