git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH V3 2/2] patch-id: fix scan_hunk_header on diffs with 1 line of before/after

From
Jerry Zhang <jerry@skydio.com>
Date
Jan 31, 2022, 23:23 UTC
Message-ID
<20220131232318.8248-2-jerry@skydio.com>
In-Reply-To
<20220131232318.8248-1-jerry@skydio.com>

Normally diffs will contain a hunk header of the format "@@ -2,2 +2,15 @@ code". However when there is only 1 line of change, the unified diff format allows for the second comma separated value to be omitted in either before or after line counts.

This can produce hunk headers that look like "@@ -2 +2,18 @@ code" or "@@ -2,2 +2 @@ code". As a result, scan_hunk_header mistakenly returns the line number as line count, which then results in unpredictable parsing errors with the rest of the patch, including giving multiple lines of output for a single commit.

Fix by explicitly setting line count to 1 when there is no comma, and add a test.

apply.c contains this same logic except it is correct. A worthwhile future project might be to unify these two diff parsers so they both benefit from fixes.

Signed-off-by: Jerry Zhang <jerry@skydio.com>
---
V2->V3:
- Made it clearer that the 1 line case is the only one where
unified diff would use this particular format.
- Cleaned up test and made separate patch to clean up old test.
 builtin/patch-id.c  |  9 +++++++--
 t/t4204-patch-id.sh | 31 ++++++++++++++++++++++++++++++-
 2 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index 822ffff51f..881fcf3273 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -30,26 +30,31 @@ static int scan_hunk_header(const char *p, int *p_before, int *p_after)
 
 	q = p + 4;
 	n = strspn(q, digits);
 	if (q[n] == ',') {
 		q += n + 1;
+		*p_before = atoi(q);
 		n = strspn(q, digits);
+	} else {
+		*p_before = 1;
 	}
+
 	if (n == 0 || q[n] != ' ' || q[n+1] != '+')
 		return 0;
 
 	r = q + n + 2;
 	n = strspn(r, digits);
 	if (r[n] == ',') {
 		r += n + 1;
+		*p_after = atoi(r);
 		n = strspn(r, digits);
+	} else {
+		*p_after = 1;
 	}
 	if (n == 0)
 		return 0;
 
-	*p_before = atoi(q);
-	*p_after = atoi(r);
 	return 1;
 }
 
 static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
 			   struct strbuf *line_buf, int stable)
diff --git a/t/t4204-patch-id.sh b/t/t4204-patch-id.sh
index da60f5b472..686ecc3c18 100755
--- a/t/t4204-patch-id.sh
+++ b/t/t4204-patch-id.sh
@@ -36,11 +36,11 @@ test_expect_success 'patch-id output is well-formed' '
 calc_patch_id () {
 	patch_name="$1"
 	shift
 	git patch-id "$@" >patch-id.output &&
 	sed "s/ .*//" patch-id.output >patch-id_"$patch_name" &&
-	test_line_count -gt 0 patch-id_"$patch_name"
+	test_line_count -eq 1 patch-id_"$patch_name"
 }
 
 get_top_diff () {
 	git log -p -1 "$@" -O bar-then-foo --
 }
@@ -198,6 +198,35 @@ test_expect_success 'patch-id handles no-nl-at-eof markers' '
 	EOF
 	calc_patch_id nonl <nonl &&
 	calc_patch_id withnl <withnl &&
 	test_cmp patch-id_nonl patch-id_withnl
 '
+
+test_expect_success 'patch-id handles diffs with one line of before/after' '
+	cat >diffu1 <<-EOF &&
+	diff --git a/bar b/bar
+	index bdaf90f..31051f6 100644
+	--- a/bar
+	+++ b/bar
+	@@ -2 +2,2 @@
+	 b
+	+c
+	diff --git a/car b/car
+	index 00750ed..2ae5e34 100644
+	--- a/car
+	+++ b/car
+	@@ -1 +1,2 @@
+	 3
+	+d
+	diff --git a/foo b/foo
+	index e439850..7146eb8 100644
+	--- a/foo
+	+++ b/foo
+	@@ -2 +2,2 @@
+	 a
+	+e
+	EOF
+	calc_patch_id diffu1 <diffu1 &&
+	test_config patchid.stable true &&
+	calc_patch_id diffu1stable <diffu1
+'
 test_done
-- 
2.32.0.1314.g6ed4fcc4cc
Previous: Jerry ZhangNext: Jerry Zhang
Message 2 of 11 in “format-patch: Fix antipatterns in tests”
  1. 1/2 format-patch: Fix antipatterns in testsJerry Zhang, Jan 31, 2022
  2. 2/2 patch-id: fix scan_hunk_header on diffs with 1 line of before/afterJerry Zhang, Jan 31, 2022
  3. 2/2 patch-id: fix scan_hunk_header on diffs with 1 line of before/afterJerry Zhang, Jan 31, 2022
  4. 2/2 patch-id: fix scan_hunk_header on diffs with 1 line of before/afterJerry Zhang, Feb 2, 2022
  5. 1/2 patch-id: Fix antipatterns in testsJerry Zhang, Jan 31, 2022
  6. Junio C HamanoJan 31, 2022
  7. 1/2 patch-id: Fix antipatterns in testsJerry Zhang, Jan 31, 2022
  8. Johannes SixtFeb 1, 2022
  9. Junio C HamanoFeb 1, 2022
  10. Junio C HamanoFeb 1, 2022
  11. 1/2 patch-id: Fix antipatterns in testsJerry Zhang, Feb 2, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.