Skip to content

Commit dd166aa

Browse files
author
Junio C Hamano
committed
blame: Notice a wholesale incorporation of an existing file.
The -C 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 <[email protected]>
1 parent e330a40 commit dd166aa

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

builtin-blame.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,39 @@ static void copy_split_if_better(struct scoreboard *sb,
890890
memcpy(best_so_far, this, sizeof(struct blame_entry [3]));
891891
}
892892

893+
/*
894+
* We are looking at a part of the final image represented by
895+
* ent (tlno and same are offset by ent->s_lno).
896+
* tlno is where we are looking at in the final image.
897+
* up to (but not including) same match preimage.
898+
* plno is where we are looking at in the preimage.
899+
*
900+
* <-------------- final image ---------------------->
901+
* <------ent------>
902+
* ^tlno ^same
903+
* <---------preimage----->
904+
* ^plno
905+
*
906+
* All line numbers are 0-based.
907+
*/
908+
static void handle_split(struct scoreboard *sb,
909+
struct blame_entry *ent,
910+
int tlno, int plno, int same,
911+
struct origin *parent,
912+
struct blame_entry *split)
913+
{
914+
if (ent->num_lines <= tlno)
915+
return;
916+
if (tlno < same) {
917+
struct blame_entry this[3];
918+
tlno += ent->s_lno;
919+
same += ent->s_lno;
920+
split_overlap(this, ent, tlno, plno, same, parent);
921+
copy_split_if_better(sb, split, this);
922+
decref_split(this);
923+
}
924+
}
925+
893926
/*
894927
* Find the lines from parent that are the same as ent so that
895928
* we can pass blames to it. file_p has the blob contents for
@@ -922,26 +955,21 @@ static void find_copy_in_blob(struct scoreboard *sb,
922955

923956
patch = compare_buffer(file_p, &file_o, 1);
924957

958+
/*
959+
* file_o is a part of final image we are annotating.
960+
* file_p partially may match that image.
961+
*/
925962
memset(split, 0, sizeof(struct blame_entry [3]));
926963
plno = tlno = 0;
927964
for (i = 0; i < patch->num; i++) {
928965
struct chunk *chunk = &patch->chunks[i];
929966

930-
/* tlno to chunk->same are the same as ent */
931-
if (ent->num_lines <= tlno)
932-
break;
933-
if (tlno < chunk->same) {
934-
struct blame_entry this[3];
935-
split_overlap(this, ent,
936-
tlno + ent->s_lno, plno,
937-
chunk->same + ent->s_lno,
938-
parent);
939-
copy_split_if_better(sb, split, this);
940-
decref_split(this);
941-
}
967+
handle_split(sb, ent, tlno, plno, chunk->same, parent, split);
942968
plno = chunk->p_next;
943969
tlno = chunk->t_next;
944970
}
971+
/* remainder, if any, all match the preimage */
972+
handle_split(sb, ent, tlno, plno, ent->num_lines, parent, split);
945973
free_patch(patch);
946974
}
947975

0 commit comments

Comments
 (0)