aboutsummaryrefslogtreecommitdiff
path: root/builtin-blame.c
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2008-07-16 02:05:20 +0400
committerJunio C Hamano <gitster@pobox.com>2008-07-15 16:38:32 -0700
commiteb46328e18688cdc3e0daaffc15c1bfc717c7527 (patch)
tree8c4c2795b587771227a6de4bdca3758e6e4ba714 /builtin-blame.c
parent6c11a5fd465eb64301093de8826c38018b474bde (diff)
downloadgit-eb46328e18688cdc3e0daaffc15c1bfc717c7527.tar.gz
git-eb46328e18688cdc3e0daaffc15c1bfc717c7527.tar.xz
Avoid rescanning unchanged entries in search for copies.
Repeatedly comparing the same entry against the same set of blobs in search for copies is quite pointless. This huge waste of effort can be avoided using a flag in the blame_entry structure. Signed-off-by: Alexander Gavrilov <angavrilov@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin-blame.c')
-rw-r--r--builtin-blame.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/builtin-blame.c b/builtin-blame.c
index 06c7de429..7ac1a3767 100644
--- a/builtin-blame.c
+++ b/builtin-blame.c
@@ -153,6 +153,10 @@ struct blame_entry {
*/
char guilty;
+ /* true if the entry has been scanned for copies in the current parent
+ */
+ char scanned;
+
/* the line number of the first line of this group in the
* suspect's file; internally all line numbers are 0 based.
*/
@@ -1040,12 +1044,12 @@ static struct blame_list *setup_blame_list(struct scoreboard *sb,
struct blame_list *blame_list = NULL;
for (e = sb->ent, num_ents = 0; e; e = e->next)
- if (!e->guilty && same_suspect(e->suspect, target))
+ if (!e->scanned && !e->guilty && same_suspect(e->suspect, target))
num_ents++;
if (num_ents) {
blame_list = xcalloc(num_ents, sizeof(struct blame_list));
for (e = sb->ent, i = 0; e; e = e->next)
- if (!e->guilty && same_suspect(e->suspect, target))
+ if (!e->scanned && !e->guilty && same_suspect(e->suspect, target))
blame_list[i++].ent = e;
}
*num_ents_p = num_ents;
@@ -1053,6 +1057,16 @@ static struct blame_list *setup_blame_list(struct scoreboard *sb,
}
/*
+ * Reset the scanned status on all entries.
+ */
+static void reset_scanned_flag(struct scoreboard *sb)
+{
+ struct blame_entry *e;
+ for (e = sb->ent; e; e = e->next)
+ e->scanned = 0;
+}
+
+/*
* For lines target is suspected for, see if we can find code movement
* across file boundary from the parent commit. porigin is the path
* in the parent we already tried.
@@ -1144,6 +1158,8 @@ static int find_copy_in_parent(struct scoreboard *sb,
split_blame(sb, split, blame_list[j].ent);
made_progress = 1;
}
+ else
+ blame_list[j].ent->scanned = 1;
decref_split(split);
}
free(blame_list);
@@ -1156,6 +1172,7 @@ static int find_copy_in_parent(struct scoreboard *sb,
break;
}
}
+ reset_scanned_flag(sb);
diff_flush(&diff_opts);
diff_tree_release_paths(&diff_opts);
return retval;