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

[PATCH 6/9] combine-diff: use an xdiff hunk callback

From
Jeff King <peff@peff.net>
Date
Nov 2, 2018, 06:38 UTC
Message-ID
<20181102063820.GF31216@sigill.intra.peff.net>
In-Reply-To
<20181102063156.GA30252@sigill.intra.peff.net>

A combined diff has to line up the hunks for all of the individual pairwise diffs, and thus needs to know their line numbers and sizes. We get that now by parsing the hunk header line that xdiff generates. However, now that xdiff supports a hunk callback, we can just use the values directly.

Signed-off-by: Jeff King <peff@peff.net>
---
I learned to love --color-moved-ws=allow-indentation-change for this
one.
 combine-diff.c | 67 +++++++++++++++++++++++++++-----------------------
 1 file changed, 36 insertions(+), 31 deletions(-)
diff --git a/combine-diff.c b/combine-diff.c
index 3c479cfc3e..ad7752ea6b 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -345,38 +345,43 @@ struct combine_diff_state {
 	struct sline *lost_bucket;
 };
 
-static void consume_line(void *state_, char *line, unsigned long len)
+static void consume_hunk(void *state_,
+			 long ob, long on,
+			 long nb, long nn,
+			 const char *funcline, long funclen)
 {
 	struct combine_diff_state *state = state_;
-	if (5 < len && !memcmp("@@ -", line, 4)) {
-		if (parse_hunk_header(line, len,
-				      &state->ob, &state->on,
-				      &state->nb, &state->nn))
-			return;
-		state->lno = state->nb;
-		if (state->nn == 0) {
-			/* @@ -X,Y +N,0 @@ removed Y lines
-			 * that would have come *after* line N
-			 * in the result.  Our lost buckets hang
-			 * to the line after the removed lines,
-			 *
-			 * Note that this is correct even when N == 0,
-			 * in which case the hunk removes the first
-			 * line in the file.
-			 */
-			state->lost_bucket = &state->sline[state->nb];
-			if (!state->nb)
-				state->nb = 1;
-		} else {
-			state->lost_bucket = &state->sline[state->nb-1];
-		}
-		if (!state->sline[state->nb-1].p_lno)
-			state->sline[state->nb-1].p_lno =
-				xcalloc(state->num_parent,
-					sizeof(unsigned long));
-		state->sline[state->nb-1].p_lno[state->n] = state->ob;
-		return;
+
+	state->ob = ob;
+	state->on = on;
+	state->nb = nb;
+	state->nn = nn;
+	state->lno = state->nb;
+	if (state->nn == 0) {
+		/* @@ -X,Y +N,0 @@ removed Y lines
+		 * that would have come *after* line N
+		 * in the result.  Our lost buckets hang
+		 * to the line after the removed lines,
+		 *
+		 * Note that this is correct even when N == 0,
+		 * in which case the hunk removes the first
+		 * line in the file.
+		 */
+		state->lost_bucket = &state->sline[state->nb];
+		if (!state->nb)
+			state->nb = 1;
+	} else {
+		state->lost_bucket = &state->sline[state->nb-1];
 	}
+	if (!state->sline[state->nb-1].p_lno)
+		state->sline[state->nb-1].p_lno =
+			xcalloc(state->num_parent, sizeof(unsigned long));
+	state->sline[state->nb-1].p_lno[state->n] = state->ob;
+}
+
+static void consume_line(void *state_, char *line, unsigned long len)
+{
+	struct combine_diff_state *state = state_;
 	if (!state->lost_bucket)
 		return; /* not in any hunk yet */
 	switch (line[0]) {
@@ -421,8 +426,8 @@ static void combine_diff(struct repository *r,
 	state.num_parent = num_parent;
 	state.n = n;
 
-	if (xdi_diff_outf(&parent_file, result_file, NULL, consume_line,
-			  &state, &xpp, &xecfg))
+	if (xdi_diff_outf(&parent_file, result_file, consume_hunk,
+			  consume_line, &state, &xpp, &xecfg))
 		die("unable to generate combined diff for %s",
 		    oid_to_hex(parent));
 	free(parent_file.ptr);
-- 
2.19.1.1336.g081079ac04
Previous: Jeff KingNext: Jeff King
Message 10 of 14 in “saner xdiff hunk callbacks”
  1. 0/9 saner xdiff hunk callbacksJeff King, Nov 2, 2018
  2. 1/9 xdiff: provide a separate emit callback for hunksJeff King, Nov 2, 2018
  3. 2/9 xdiff-interface: provide a separate consume callback for hunksJeff King, Nov 2, 2018
  4. 3/9 diff: avoid generating unused hunk header linesJeff King, Nov 2, 2018
  5. Stefan BellerNov 2, 2018
  6. Jeff KingNov 2, 2018
  7. Junio C HamanoNov 3, 2018
  8. 4/9 diff: discard hunk headers for patch-ids earlierJeff King, Nov 2, 2018
  9. 5/9 diff: use hunk callback for word-diffJeff King, Nov 2, 2018
  10. 6/9 combine-diff: use an xdiff hunk callbackJeff King, Nov 2, 2018
  11. 7/9 diff: convert --check to use a hunk callbackJeff King, Nov 2, 2018
  12. 8/9 range-diff: use a hunk callbackJeff King, Nov 2, 2018
  13. 9/9 xdiff-interface: drop parse_hunk_header()Jeff King, Nov 2, 2018
  14. Junio C HamanoNov 2, 2018

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.