replay: fail gracefully when a merge input is unreadable
When objects involved in the merge cannot be read, the merge machinery will return early with result.clean = -1, and result.tree left as NULL. pick_regular_commit() tested only "if (!result->clean)", ignoring the case where "clean < 0". That causes the code to try to use result->tree, resulting in a SIGSEGV. Handle clean < 0 explicitly; the merge machinery will already have printed messages such as "Could not read <object>" and "collecting merge info failed for trees...", so we don't need to add much detail beyond the fact that the merge failed. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>seen
parent
48fc56621c
commit
b6f5e80fdf
7
replay.c
7
replay.c
|
|
@ -327,6 +327,13 @@ static struct commit *pick_regular_commit(struct repository *repo,
|
|||
merge_opt->ancestor = NULL;
|
||||
merge_opt->branch2 = NULL;
|
||||
|
||||
if (result->clean < 0) {
|
||||
error(_("merge of %s onto %s failed"),
|
||||
oid_to_hex(&pickme->object.oid),
|
||||
oid_to_hex(&replayed_base->object.oid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!result->clean)
|
||||
return NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -565,4 +565,38 @@ test_expect_success '--onto with --ref rejects multiple revision ranges' '
|
|||
test_grep "cannot be used with multiple revision ranges" err
|
||||
'
|
||||
|
||||
test_expect_success 'replay fails without segfault when objects are missing' '
|
||||
test_when_finished "rm -fr unreadable" &&
|
||||
git init unreadable &&
|
||||
(
|
||||
cd unreadable &&
|
||||
|
||||
test_write_lines l1 l2 l3 l4 l5 l6 l7 l8 >f &&
|
||||
git add f &&
|
||||
git commit -m base &&
|
||||
git branch base &&
|
||||
|
||||
test_write_lines l1 l2 l3 l4 l5 l6 l7 CHANGED >f &&
|
||||
git commit -am side &&
|
||||
git branch side &&
|
||||
|
||||
git switch -c onto base &&
|
||||
test_write_lines CHANGED l2 l3 l4 l5 l6 l7 l8 >f &&
|
||||
git commit -am onto &&
|
||||
|
||||
# The replay works while every object is readable.
|
||||
git replay --onto onto base..side &&
|
||||
|
||||
# Removing the onto tree makes parse_tree() fail during the
|
||||
# incore merge, driving clean < 0 with a NULL result tree.
|
||||
onto_tree=$(git rev-parse onto^{tree}) &&
|
||||
obj=$(test_oid_to_path "$onto_tree") &&
|
||||
mv .git/objects/${obj} saved-tree &&
|
||||
|
||||
# Ensure replay gracefully handles the missing object
|
||||
test_must_fail git replay --onto onto base..side 2>err &&
|
||||
test_grep -e "Could not read" -e "collecting merge info failed" err
|
||||
)
|
||||
'
|
||||
|
||||
test_done
|
||||
|
|
|
|||
Loading…
Reference in New Issue