Skip to content

Commit 3ea43bb

Browse files
committed
Merge branch 'jc/abort-ll-merge-with-a-signal'
When the external merge driver is killed by a signal, its output should not be trusted as a resolution with conflicts that is proposed by the driver, but the code did. * jc/abort-ll-merge-with-a-signal: t6406: skip "external merge driver getting killed by a signal" test on Windows ll-merge: killing the external merge driver aborts the merge
2 parents a1264a0 + 34d765e commit 3ea43bb

File tree

3 files changed

+35
-2
lines changed

3 files changed

+35
-2
lines changed

Documentation/gitattributes.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1132,7 +1132,10 @@ size (see below).
11321132
The merge driver is expected to leave the result of the merge in
11331133
the file named with `%A` by overwriting it, and exit with zero
11341134
status if it managed to merge them cleanly, or non-zero if there
1135-
were conflicts.
1135+
were conflicts. When the driver crashes (e.g. killed by SEGV),
1136+
it is expected to exit with non-zero status that are higher than
1137+
128, and in such a case, the merge results in a failure (which is
1138+
different from producing a conflict).
11361139

11371140
The `merge.*.recursive` variable specifies what other merge
11381141
driver to use when the merge driver is called for an internal

merge-ll.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,14 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn,
243243
unlink_or_warn(temp[i]);
244244
strbuf_release(&cmd);
245245
strbuf_release(&path_sq);
246-
ret = (status > 0) ? LL_MERGE_CONFLICT : status;
246+
247+
if (!status)
248+
ret = LL_MERGE_OK;
249+
else if (status <= 128)
250+
ret = LL_MERGE_CONFLICT;
251+
else
252+
/* died due to a signal: WTERMSIG(status) + 128 */
253+
ret = LL_MERGE_ERROR;
247254
return ret;
248255
}
249256

t/t6406-merge-attr.sh

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ test_expect_success setup '
5656
) >"$ours+"
5757
cat "$ours+" >"$ours"
5858
rm -f "$ours+"
59+
60+
if test -f ./please-abort
61+
then
62+
echo >>./please-abort killing myself
63+
kill -9 $$
64+
fi
5965
exit "$exit"
6066
EOF
6167
chmod +x ./custom-merge
@@ -162,6 +168,23 @@ test_expect_success 'custom merge backend' '
162168
rm -f $o $a $b
163169
'
164170

171+
test_expect_success !WINDOWS 'custom merge driver that is killed with a signal' '
172+
test_when_finished "rm -f output please-abort" &&
173+
174+
git reset --hard anchor &&
175+
git config --replace-all \
176+
merge.custom.driver "./custom-merge %O %A %B 0 %P" &&
177+
git config --replace-all \
178+
merge.custom.name "custom merge driver for testing" &&
179+
180+
>./please-abort &&
181+
echo "* merge=custom" >.gitattributes &&
182+
test_must_fail git merge main &&
183+
git ls-files -u >output &&
184+
git diff --name-only HEAD >>output &&
185+
test_must_be_empty output
186+
'
187+
165188
test_expect_success 'up-to-date merge without common ancestor' '
166189
git init repo1 &&
167190
git init repo2 &&

0 commit comments

Comments
 (0)