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

[PATCH 1/3] blame: handle the tail-match correctly in -C/-M

From
Junio C Hamano <junkio@cox.net>
Date
May 6, 2007, 06:02 UTC
Message-ID
<11784313631165-git-send-email-junkio@cox.net>

The -C/-M option to blame tries to find a section of a preimage file by running diff against the lines whose origin is still unknown, and excluding the different parts. The code however did not cover the case where the tail part of the section matched, which we handle for the normal non-move/copy codepath.

This breakage was most visible when preimage file matches in its entirety and failed to pass blame in such a case.

Signed-off-by: Junio C Hamano <junkio@cox.net>
---
 builtin-blame.c |   52 ++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/builtin-blame.c b/builtin-blame.c
index 8919b02..f8843e6 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -891,6 +891,39 @@ static void copy_split_if_better(struct scoreboard *sb,
 }
 
 /*
+ * We are looking at a part of the final image represented by
+ * ent (tlno and same are offset by ent->s_lno).
+ * tlno is where we are looking at in the final image.
+ * up to (but not including) same match preimage.
+ * plno is where we are looking at in the preimage.
+ *
+ * <-------------- final image ---------------------->
+ *       <------ent------>
+ *         ^tlno ^same
+ *    <---------preimage----->
+ *         ^plno
+ *
+ * All line numbers are 0-based.
+ */
+static void handle_split(struct scoreboard *sb,
+			 struct blame_entry *ent,
+			 int tlno, int plno, int same,
+			 struct origin *parent,
+			 struct blame_entry *split)
+{
+	if (ent->num_lines <= tlno)
+		return;
+	if (tlno < same) {
+		struct blame_entry this[3];
+		tlno += ent->s_lno;
+		same += ent->s_lno;
+		split_overlap(this, ent, tlno, plno, same, parent);
+		copy_split_if_better(sb, split, this);
+		decref_split(this);
+	}
+}
+
+/*
  * Find the lines from parent that are the same as ent so that
  * we can pass blames to it.  file_p has the blob contents for
  * the parent.
@@ -922,26 +955,21 @@ static void find_copy_in_blob(struct scoreboard *sb,
 
 	patch = compare_buffer(file_p, &file_o, 1);
 
+	/*
+	 * file_o is a part of final image we are annotating.
+	 * file_p partially may match that image.
+	 */
 	memset(split, 0, sizeof(struct blame_entry [3]));
 	plno = tlno = 0;
 	for (i = 0; i < patch->num; i++) {
 		struct chunk *chunk = &patch->chunks[i];
 
-		/* tlno to chunk->same are the same as ent */
-		if (ent->num_lines <= tlno)
-			break;
-		if (tlno < chunk->same) {
-			struct blame_entry this[3];
-			split_overlap(this, ent,
-				      tlno + ent->s_lno, plno,
-				      chunk->same + ent->s_lno,
-				      parent);
-			copy_split_if_better(sb, split, this);
-			decref_split(this);
-		}
+		handle_split(sb, ent, tlno, plno, chunk->same, parent, split);
 		plno = chunk->p_next;
 		tlno = chunk->t_next;
 	}
+	/* remainder, if any, all match the preimage */
+	handle_split(sb, ent, tlno, plno, ent->num_lines, parent, split);
 	free_patch(patch);
 }
 
-- 
1.5.2.rc1.709.g9462
Next: Junio C Hamano
Message 1 of 3 in “blame: handle the tail-match correctly in -C/-M”
  1. 1/3 blame: handle the tail-match correctly in -C/-MJunio C Hamano, May 6, 2007
  2. 2/3 blame: -C -C -CJunio C Hamano, May 6, 2007
  3. 3/3 Add test for blame corner cases.Junio C Hamano, May 6, 2007

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.