Merge branch 'jk/has-uncommitted-changes-fix'

"git pull --rebase" on a corrupt HEAD caused a segfault.  In
general we substitute an empty tree object when running the in-core
equivalent of the diff-index command, and the codepath has been
corrected to do so as well to fix this issue.

* jk/has-uncommitted-changes-fix:
  has_uncommitted_changes(): fall back to empty tree
This commit is contained in:
Junio C Hamano 2018-08-02 15:30:37 -07:00
commit 218608cacd
3 changed files with 25 additions and 0 deletions

View file

@ -520,6 +520,9 @@ int run_diff_index(struct rev_info *revs, int cached)
struct object_array_entry *ent;
uint64_t start = getnanotime();
if (revs->pending.nr != 1)
BUG("run_diff_index must be passed exactly one tree");
ent = revs->pending.objects;
if (diff_cache(revs, &ent->item->oid, ent->name, cached))
exit(128);

View file

@ -618,6 +618,18 @@ test_expect_success 'pull --rebase fails on unborn branch with staged changes' '
)
'
test_expect_success 'pull --rebase fails on corrupt HEAD' '
test_when_finished "rm -rf corrupt" &&
git init corrupt &&
(
cd corrupt &&
test_commit one &&
obj=$(git rev-parse --verify HEAD | sed "s#^..#&/#") &&
rm -f .git/objects/$obj &&
test_must_fail git pull --rebase
)
'
test_expect_success 'setup for detecting upstreamed changes' '
mkdir src &&
(cd src &&

View file

@ -2340,7 +2340,17 @@ int has_uncommitted_changes(int ignore_submodules)
if (ignore_submodules)
rev_info.diffopt.flags.ignore_submodules = 1;
rev_info.diffopt.flags.quick = 1;
add_head_to_pending(&rev_info);
if (!rev_info.pending.nr) {
/*
* We have no head (or it's corrupt); use the empty tree,
* which will complain if the index is non-empty.
*/
struct tree *tree = lookup_tree(the_hash_algo->empty_tree);
add_pending_object(&rev_info, &tree->object, "");
}
diff_setup_done(&rev_info.diffopt);
result = run_diff_index(&rev_info, 1);
return diff_result_code(&rev_info.diffopt, result);