Skip to content

Commit 84ac6e4

Browse files
Barret Rhodengitster
authored andcommitted
blame: optionally track line fingerprints during fill_blame_origin()
fill_blame_origin() is a convenient place to store data that we will use throughout the lifetime of a blame_origin. Some heuristics for ignoring commits during a blame session can make use of this storage. In particular, we will calculate a fingerprint for each line of a file for blame_origins involved in an ignored commit. In this commit, we only calculate the line_starts, reusing the existing code from the scoreboard's line_starts. In an upcoming commit, we will actually compute the fingerprints. This feature will be used when we attempt to pass blame entries to parents when we "ignore" a commit. Most uses of fill_blame_origin() will not require this feature, hence the flag parameter. Multiple calls to fill_blame_origin() are idempotent, and any of them can request the creation of the fingerprints structure. Suggested-by: Michael Platings <[email protected]> Signed-off-by: Barret Rhoden <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d0738d9 commit 84ac6e4

File tree

2 files changed

+67
-30
lines changed

2 files changed

+67
-30
lines changed

blame.c

Lines changed: 65 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -310,12 +310,63 @@ static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b,
310310
return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
311311
}
312312

313+
static const char *get_next_line(const char *start, const char *end)
314+
{
315+
const char *nl = memchr(start, '\n', end - start);
316+
317+
return nl ? nl + 1 : end;
318+
}
319+
320+
static int find_line_starts(int **line_starts, const char *buf,
321+
unsigned long len)
322+
{
323+
const char *end = buf + len;
324+
const char *p;
325+
int *lineno;
326+
int num = 0;
327+
328+
for (p = buf; p < end; p = get_next_line(p, end))
329+
num++;
330+
331+
ALLOC_ARRAY(*line_starts, num + 1);
332+
lineno = *line_starts;
333+
334+
for (p = buf; p < end; p = get_next_line(p, end))
335+
*lineno++ = p - buf;
336+
337+
*lineno = len;
338+
339+
return num;
340+
}
341+
342+
static void fill_origin_fingerprints(struct blame_origin *o, mmfile_t *file)
343+
{
344+
int *line_starts;
345+
346+
if (o->fingerprints)
347+
return;
348+
o->num_lines = find_line_starts(&line_starts, o->file.ptr,
349+
o->file.size);
350+
/* TODO: Will fill in fingerprints in a future commit */
351+
o->fingerprints = xcalloc(sizeof(struct fingerprint), o->num_lines);
352+
free(line_starts);
353+
}
354+
355+
static void drop_origin_fingerprints(struct blame_origin *o)
356+
{
357+
if (o->fingerprints) {
358+
o->num_lines = 0;
359+
FREE_AND_NULL(o->fingerprints);
360+
}
361+
}
362+
313363
/*
314364
* Given an origin, prepare mmfile_t structure to be used by the
315365
* diff machinery
316366
*/
317367
static void fill_origin_blob(struct diff_options *opt,
318-
struct blame_origin *o, mmfile_t *file, int *num_read_blob)
368+
struct blame_origin *o, mmfile_t *file,
369+
int *num_read_blob, int fill_fingerprints)
319370
{
320371
if (!o->file.ptr) {
321372
enum object_type type;
@@ -339,11 +390,14 @@ static void fill_origin_blob(struct diff_options *opt,
339390
}
340391
else
341392
*file = o->file;
393+
if (fill_fingerprints)
394+
fill_origin_fingerprints(o, file);
342395
}
343396

344397
static void drop_origin_blob(struct blame_origin *o)
345398
{
346399
FREE_AND_NULL(o->file.ptr);
400+
drop_origin_fingerprints(o);
347401
}
348402

349403
/*
@@ -1135,8 +1189,10 @@ static void pass_blame_to_parent(struct blame_scoreboard *sb,
11351189
d.ignore_diffs = ignore_diffs;
11361190
d.dstq = &newdest; d.srcq = &target->suspects;
11371191

1138-
fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
1139-
fill_origin_blob(&sb->revs->diffopt, target, &file_o, &sb->num_read_blob);
1192+
fill_origin_blob(&sb->revs->diffopt, parent, &file_p,
1193+
&sb->num_read_blob, ignore_diffs);
1194+
fill_origin_blob(&sb->revs->diffopt, target, &file_o,
1195+
&sb->num_read_blob, ignore_diffs);
11401196
sb->num_get_patch++;
11411197

11421198
if (diff_hunks(&file_p, &file_o, blame_chunk_cb, &d, sb->xdl_opts))
@@ -1347,7 +1403,8 @@ static void find_move_in_parent(struct blame_scoreboard *sb,
13471403
if (!unblamed)
13481404
return; /* nothing remains for this target */
13491405

1350-
fill_origin_blob(&sb->revs->diffopt, parent, &file_p, &sb->num_read_blob);
1406+
fill_origin_blob(&sb->revs->diffopt, parent, &file_p,
1407+
&sb->num_read_blob, 0);
13511408
if (!file_p.ptr)
13521409
return;
13531410

@@ -1476,7 +1533,8 @@ static void find_copy_in_parent(struct blame_scoreboard *sb,
14761533
norigin = get_origin(parent, p->one->path);
14771534
oidcpy(&norigin->blob_oid, &p->one->oid);
14781535
norigin->mode = p->one->mode;
1479-
fill_origin_blob(&sb->revs->diffopt, norigin, &file_p, &sb->num_read_blob);
1536+
fill_origin_blob(&sb->revs->diffopt, norigin, &file_p,
1537+
&sb->num_read_blob, 0);
14801538
if (!file_p.ptr)
14811539
continue;
14821540

@@ -1815,37 +1873,14 @@ void assign_blame(struct blame_scoreboard *sb, int opt)
18151873
}
18161874
}
18171875

1818-
static const char *get_next_line(const char *start, const char *end)
1819-
{
1820-
const char *nl = memchr(start, '\n', end - start);
1821-
return nl ? nl + 1 : end;
1822-
}
1823-
18241876
/*
18251877
* To allow quick access to the contents of nth line in the
18261878
* final image, prepare an index in the scoreboard.
18271879
*/
18281880
static int prepare_lines(struct blame_scoreboard *sb)
18291881
{
1830-
const char *buf = sb->final_buf;
1831-
unsigned long len = sb->final_buf_size;
1832-
const char *end = buf + len;
1833-
const char *p;
1834-
int *lineno;
1835-
int num = 0;
1836-
1837-
for (p = buf; p < end; p = get_next_line(p, end))
1838-
num++;
1839-
1840-
ALLOC_ARRAY(sb->lineno, num + 1);
1841-
lineno = sb->lineno;
1842-
1843-
for (p = buf; p < end; p = get_next_line(p, end))
1844-
*lineno++ = p - buf;
1845-
1846-
*lineno = len;
1847-
1848-
sb->num_lines = num;
1882+
sb->num_lines = find_line_starts(&sb->lineno, sb->final_buf,
1883+
sb->final_buf_size);
18491884
return sb->num_lines;
18501885
}
18511886

blame.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ struct blame_origin {
5151
*/
5252
struct blame_entry *suspects;
5353
mmfile_t file;
54+
int num_lines;
55+
void *fingerprints;
5456
struct object_id blob_oid;
5557
unsigned mode;
5658
/* guilty gets set when shipping any suspects to the final

0 commit comments

Comments
 (0)