Merge branch 'jc/abort-ll-merge-with-a-signal' into next

* jc/abort-ll-merge-with-a-signal:
  ll-merge: killing the external merge driver aborts the merge
This commit is contained in:
Junio C Hamano
2023-06-23 11:22:57 -07:00
3 changed files with 35 additions and 2 deletions

View File

@ -1132,7 +1132,10 @@ size (see below).
The merge driver is expected to leave the result of the merge in The merge driver is expected to leave the result of the merge in
the file named with `%A` by overwriting it, and exit with zero the file named with `%A` by overwriting it, and exit with zero
status if it managed to merge them cleanly, or non-zero if there status if it managed to merge them cleanly, or non-zero if there
were conflicts. were conflicts. When the driver crashes (e.g. killed by SEGV),
it is expected to exit with non-zero status that are higher than
128, and in such a case, the merge results in a failure (which is
different from producing a conflict).
The `merge.*.recursive` variable specifies what other merge The `merge.*.recursive` variable specifies what other merge
driver to use when the merge driver is called for an internal driver to use when the merge driver is called for an internal

View File

@ -243,7 +243,14 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
unlink_or_warn(temp[i]); unlink_or_warn(temp[i]);
strbuf_release(&cmd); strbuf_release(&cmd);
strbuf_release(&path_sq); strbuf_release(&path_sq);
ret = (status > 0) ? LL_MERGE_CONFLICT : status;
if (!status)
ret = LL_MERGE_OK;
else if (status <= 128)
ret = LL_MERGE_CONFLICT;
else
/* died due to a signal: WTERMSIG(status) + 128 */
ret = LL_MERGE_ERROR;
return ret; return ret;
} }

View File

@ -56,6 +56,12 @@ test_expect_success setup '
) >"$ours+" ) >"$ours+"
cat "$ours+" >"$ours" cat "$ours+" >"$ours"
rm -f "$ours+" rm -f "$ours+"
if test -f ./please-abort
then
echo >>./please-abort killing myself
kill -9 $$
fi
exit "$exit" exit "$exit"
EOF EOF
chmod +x ./custom-merge chmod +x ./custom-merge
@ -162,6 +168,23 @@ test_expect_success 'custom merge backend' '
rm -f $o $a $b rm -f $o $a $b
' '
test_expect_success 'custom merge driver that is killed with a signal' '
test_when_finished "rm -f output please-abort" &&
git reset --hard anchor &&
git config --replace-all \
merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
git config --replace-all \
merge.custom.name "custom merge driver for testing" &&
>./please-abort &&
echo "* merge=custom" >.gitattributes &&
test_must_fail git merge main &&
git ls-files -u >output &&
git diff --name-only HEAD >>output &&
test_must_be_empty output
'
test_expect_success 'up-to-date merge without common ancestor' ' test_expect_success 'up-to-date merge without common ancestor' '
git init repo1 && git init repo1 &&
git init repo2 && git init repo2 &&