summaryrefslogtreecommitdiff
path: root/blame.c
diff options
context:
space:
mode:
Diffstat (limited to 'blame.c')
-rw-r--r--blame.c90
1 files changed, 60 insertions, 30 deletions
diff --git a/blame.c b/blame.c
index 472ee67ae2..13e1e931fd 100644
--- a/blame.c
+++ b/blame.c
@@ -310,12 +310,58 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
}
+static const char *get_next_line(const char *start, const char *end)
+{
+ const char *nl = memchr(start, '\n', end - start);
+
+ return nl ? nl + 1 : end;
+}
+
+static int find_line_starts(int **line_starts, const char *buf,
+ unsigned long len)
+{
+ const char *end = buf + len;
+ const char *p;
+ int *lineno;
+ int num = 0;
+
+ for (p = buf; p < end; p = get_next_line(p, end))
+ num++;
+
+ ALLOC_ARRAY(*line_starts, num + 1);
+ lineno = *line_starts;
+
+ for (p = buf; p < end; p = get_next_line(p, end))
+ *lineno++ = p - buf;
+
+ *lineno = len;
+
+ return num;
+}
+
+static void fill_origin_fingerprints(struct blame_origin *o, mmfile_t *file)
+{
+ int *line_starts;
+
+ if (o->fingerprints)
+ return;
+ o->num_lines = find_line_starts(&line_starts, o->file.ptr,
+ o->file.size);
+ /* TODO: Will fill in fingerprints in a future commit */
+ free(line_starts);
+}
+
+static void drop_origin_fingerprints(struct blame_origin *o)
+{
+}
+
/*
* Given an origin, prepare mmfile_t structure to be used by the
* diff machinery
*/
static void fill_origin_blob(struct diff_options *opt,
- struct blame_origin *o, mmfile_t *file, int *num_read_blob)
+ struct blame_origin *o, mmfile_t *file,
+ int *num_read_blob, int fill_fingerprints)
{
if (!o->file.ptr) {
enum object_type type;
@@ -339,11 +385,14 @@ static void fill_origin_blob(struct diff_options *opt,
}
else
*file = o->file;
+ if (fill_fingerprints)
+ fill_origin_fingerprints(o, file);
}
static void drop_origin_blob(struct blame_origin *o)
{
FREE_AND_NULL(o->file.ptr);
+ drop_origin_fingerprints(o);
}
/*
@@ -1140,8 +1189,10 @@ static void pass_blame_to_parent(struct blame_scoreboard *sb,
d.ignore_diffs = ignore_diffs;
d.dstq = &newdest; d.srcq = &target->suspects;
- fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
- fill_origin_blob(&sb->revs->diffopt, target, &file_o, &sb->num_read_blob);
+ fill_origin_blob(&sb->revs->diffopt, parent, &file_p,
+ &sb->num_read_blob, ignore_diffs);
+ fill_origin_blob(&sb->revs->diffopt, target, &file_o,
+ &sb->num_read_blob, ignore_diffs);
sb->num_get_patch++;
if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, sb->xdl_opts))
@@ -1352,7 +1403,8 @@ static void find_move_in_parent(struct blame_scoreboard *sb,
if (!unblamed)
return; /* nothing remains for this target */
- fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
+ fill_origin_blob(&sb->revs->diffopt, parent, &file_p,
+ &sb->num_read_blob, 0);
if (!file_p.ptr)
return;
@@ -1481,7 +1533,8 @@ static void find_copy_in_parent(struct blame_scoreboard *sb,
norigin = get_origin(parent, p->one->path);
oidcpy(&norigin->blob_oid, &p->one->oid);
norigin->mode = p->one->mode;
- fill_origin_blob(&sb->revs->diffopt, norigin, &file_p, &sb->num_read_blob);
+ fill_origin_blob(&sb->revs->diffopt, norigin, &file_p,
+ &sb->num_read_blob, 0);
if (!file_p.ptr)
continue;
@@ -1820,37 +1873,14 @@ void assign_blame(struct blame_scoreboard *sb, int opt)
}
}
-static const char *get_next_line(const char *start, const char *end)
-{
- const char *nl = memchr(start, '\n', end - start);
- return nl ? nl + 1 : end;
-}
-
/*
* To allow quick access to the contents of nth line in the
* final image, prepare an index in the scoreboard.
*/
static int prepare_lines(struct blame_scoreboard *sb)
{
- const char *buf = sb->final_buf;
- unsigned long len = sb->final_buf_size;
- const char *end = buf + len;
- const char *p;
- int *lineno;
- int num = 0;
-
- for (p = buf; p < end; p = get_next_line(p, end))
- num++;
-
- ALLOC_ARRAY(sb->lineno, num + 1);
- lineno = sb->lineno;
-
- for (p = buf; p < end; p = get_next_line(p, end))
- *lineno++ = p - buf;
-
- *lineno = len;
-
- sb->num_lines = num;
+ sb->num_lines = find_line_starts(&sb->lineno, sb->final_buf,
+ sb->final_buf_size);
return sb->num_lines;
}