apply: report the location of corrupt patches
When parsing a corrupt patch, git apply reports only the line number. That does not tell the user which input the line number refers to. Include the patch input path in the error message so the reported location is easier to use. Reset the line number for each patch input so the reported location stays correct when multiple input files are provided. Add tests for file input, standard input, multiple patch inputs, and existing binary-diff corrupt patch cases. Signed-off-by: Jialong Wang <jerrywang183@yahoo.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jialong Wang committed
Mar 17, 2026 at 12:23 UTC
c5e15c9a58c0b32ec8be3ae96434834124de175e
3 files changed
+42
-4
apply.c
+3
-1
@@ -1875,7 +1875,8 @@ static int parse_single_patch(struct apply_state *state,
1875
len = parse_fragment(state, line, size, patch, fragment);
1876
if (len <= 0) {
1877
free(fragment);
1878
- return error(_("corrupt patch at line %d"), state->linenr);
1878
+ return error(_("corrupt patch at %s:%d"),
1879
+ state->patch_input_file, state->linenr);
1880
}
1881
fragment->patch = line;
1882
fragment->size = len;
@@ -4825,6 +4826,7 @@ static int apply_patch(struct apply_state *state,
4826
int flush_attributes = 0;
4827
4828
state->patch_input_file = filename;
4829
+ state->linenr = 1;
4830
if (read_patch_file(&buf, fd) < 0)
4831
return -128;
4832
offset = 0;
t/t4012-diff-binary.sh
+2
-2
@@ -68,7 +68,7 @@ test_expect_success 'apply detecting corrupt patch correctly' '
68
sed -e "s/-CIT/xCIT/" <output >broken &&
69
test_must_fail git apply --stat --summary broken 2>detected &&
70
detected=$(cat detected) &&
71
- detected=$(expr "$detected" : "error.*at line \\([0-9]*\\)\$") &&
71
+ detected=$(expr "$detected" : "error.*broken:\\([0-9]*\\)\$") &&
72
detected=$(sed -ne "${detected}p" broken) &&
73
test "$detected" = xCIT
74
'
@@ -77,7 +77,7 @@ test_expect_success 'apply detecting corrupt patch correctly' '
77
git diff --binary | sed -e "s/-CIT/xCIT/" >broken &&
78
test_must_fail git apply --stat --summary broken 2>detected &&
79
detected=$(cat detected) &&
80
- detected=$(expr "$detected" : "error.*at line \\([0-9]*\\)\$") &&
80
+ detected=$(expr "$detected" : "error.*broken:\\([0-9]*\\)\$") &&
81
detected=$(sed -ne "${detected}p" broken) &&
82
test "$detected" = xCIT
83
'
t/t4100-apply-stat.sh
+37
-1
@@ -48,7 +48,43 @@ test_expect_success 'applying a hunk header which overflows fails' '
48
+b
49
EOF
50
test_must_fail git apply patch 2>err &&
51
- echo "error: corrupt patch at line 4" >expect &&
51
+ echo "error: corrupt patch at patch:4" >expect &&
52
+ test_cmp expect err
53
+'
54
+
55
+test_expect_success 'applying a hunk header which overflows from stdin fails' '
56
+ cat >patch <<-\EOF &&
57
+ diff -u a/file b/file
58
+ --- a/file
59
+ +++ b/file
60
+ @@ -98765432109876543210 +98765432109876543210 @@
61
+ -a
62
+ +b
63
+ EOF
64
+ test_must_fail git apply <patch 2>err &&
65
+ echo "error: corrupt patch at <stdin>:4" >expect &&
66
+ test_cmp expect err
67
+'
68
+
69
+test_expect_success 'applying multiple patches reports the corrupted input' '
70
+ cat >good.patch <<-\EOF &&
71
+ diff -u a/file b/file
72
+ --- a/file
73
+ +++ b/file
74
+ @@ -1 +1 @@
75
+ -a
76
+ +b
77
+ EOF
78
+ cat >bad.patch <<-\EOF &&
79
+ diff -u a/file b/file
80
+ --- a/file
81
+ +++ b/file
82
+ @@ -98765432109876543210 +98765432109876543210 @@
83
+ -a
84
+ +b
85
+ EOF
86
+ test_must_fail git apply --stat --summary good.patch bad.patch 2>err &&
87
+ echo "error: corrupt patch at bad.patch:4" >expect &&
88
test_cmp expect err
89
'
90
test_done