зеркало из https://github.com/microsoft/git.git
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 <michael@platin.gs> Signed-off-by: Barret Rhoden <brho@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Родитель
8934ac8c92
Коммит
1fc73384ba
90
blame.c
90
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;
|
||||
}
|
||||
|
||||
|
|
2
blame.h
2
blame.h
|
@ -51,6 +51,8 @@ struct blame_origin {
|
|||
*/
|
||||
struct blame_entry *suspects;
|
||||
mmfile_t file;
|
||||
int num_lines;
|
||||
void *fingerprints;
|
||||
struct object_id blob_oid;
|
||||
unsigned mode;
|
||||
/* guilty gets set when shipping any suspects to the final
|
||||
|
|
Загрузка…
Ссылка в новой задаче