mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-10 18:28:16 +00:00
Clean up ported code
This commit is contained in:
parent
77db6ff5c7
commit
b6f60a4d96
24
src/blame.c
24
src/blame.c
@ -260,6 +260,8 @@ static int load_blob(git_blame *blame)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
|
if (blame->final_blob) return 0;
|
||||||
|
|
||||||
error = git_commit_lookup(&blame->final, blame->repository, &blame->options.newest_commit);
|
error = git_commit_lookup(&blame->final, blame->repository, &blame->options.newest_commit);
|
||||||
if (error < 0)
|
if (error < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@ -276,20 +278,13 @@ static int blame_internal(git_blame *blame)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
git_blame__entry *ent = NULL;
|
git_blame__entry *ent = NULL;
|
||||||
git_blob *blob = NULL;
|
|
||||||
git_blame__origin *o;
|
git_blame__origin *o;
|
||||||
|
|
||||||
if ((error = git_commit_lookup(&blame->final, blame->repository,
|
if ((error = load_blob(blame)) < 0 ||
|
||||||
&blame->options.newest_commit))
|
(error = git_blame__get_origin(&o, blame, blame->final, blame->path)) < 0)
|
||||||
< 0 ||
|
|
||||||
(error = git_object_lookup_bypath((git_object**)&blob, (git_object*)blame->final,
|
|
||||||
blame->path, GIT_OBJ_BLOB))
|
|
||||||
< 0)
|
|
||||||
goto cleanup;
|
|
||||||
blame->final_buf = git_blob_rawcontent(blob);
|
|
||||||
blame->final_buf_size = git_blob_rawsize(blob);
|
|
||||||
if ((error = get_origin(&o, blame, blame->final, blame->path)) < 0)
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
blame->final_buf = git_blob_rawcontent(blame->final_blob);
|
||||||
|
blame->final_buf_size = git_blob_rawsize(blame->final_blob);
|
||||||
|
|
||||||
ent = git__calloc(1, sizeof(git_blame__entry));
|
ent = git__calloc(1, sizeof(git_blame__entry));
|
||||||
ent->num_lines = index_blob_lines(blame);
|
ent->num_lines = index_blob_lines(blame);
|
||||||
@ -303,8 +298,7 @@ static int blame_internal(git_blame *blame)
|
|||||||
blame->ent = ent;
|
blame->ent = ent;
|
||||||
blame->path = blame->path;
|
blame->path = blame->path;
|
||||||
|
|
||||||
assign_blame(blame, blame->options.flags);
|
git_blame__like_git(blame, blame->options.flags);
|
||||||
coalesce(blame);
|
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
for (ent = blame->ent; ent; ) {
|
for (ent = blame->ent; ent; ) {
|
||||||
@ -312,12 +306,10 @@ cleanup:
|
|||||||
|
|
||||||
git_vector_insert(&blame->hunks, hunk_from_entry(ent));
|
git_vector_insert(&blame->hunks, hunk_from_entry(ent));
|
||||||
|
|
||||||
origin_decref(ent->suspect);
|
git_blame__free_entry(ent);
|
||||||
git__free(ent);
|
|
||||||
ent = e;
|
ent = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
git_blob_free(blob);
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
227
src/blame_git.c
227
src/blame_git.c
@ -7,30 +7,32 @@
|
|||||||
|
|
||||||
#include "blame_git.h"
|
#include "blame_git.h"
|
||||||
#include "commit.h"
|
#include "commit.h"
|
||||||
#include "xdiff/xinclude.h"
|
#include "blob.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Locate an existing origin or create a new one.
|
* Origin is refcounted and usually we keep the blob contents to be
|
||||||
|
* reused.
|
||||||
*/
|
*/
|
||||||
int get_origin(git_blame__origin **out, git_blame *blame, git_commit *commit, const char *path)
|
static git_blame__origin *origin_incref(git_blame__origin *o)
|
||||||
{
|
{
|
||||||
git_blame__entry *e;
|
if (o)
|
||||||
|
o->refcnt++;
|
||||||
for (e = blame->ent; e; e = e->next) {
|
return o;
|
||||||
if (e->suspect->commit == commit && !strcmp(e->suspect->path, path)) {
|
|
||||||
*out = origin_incref(e->suspect);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return make_origin(out, commit, path);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void origin_decref(git_blame__origin *o)
|
||||||
* Given a commit and a path in it, create a new origin structure.
|
{
|
||||||
* The callers that add blame to the scoreboard should use
|
if (o && --o->refcnt <= 0) {
|
||||||
* get_origin() to obtain shared, refcounted copy instead of calling
|
if (o->previous)
|
||||||
* this function directly.
|
origin_decref(o->previous);
|
||||||
*/
|
git_blob_free(o->blob);
|
||||||
int make_origin(git_blame__origin **out, git_commit *commit, const char *path)
|
git_commit_free(o->commit);
|
||||||
|
git__free(o);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a commit and a path in it, create a new origin structure. */
|
||||||
|
static int make_origin(git_blame__origin **out, git_commit *commit, const char *path)
|
||||||
{
|
{
|
||||||
int error = 0;
|
int error = 0;
|
||||||
git_blame__origin *o;
|
git_blame__origin *o;
|
||||||
@ -50,13 +52,30 @@ int make_origin(git_blame__origin **out, git_commit *commit, const char *path)
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct blame_chunk_cb_data {
|
/* Locate an existing origin or create a new one. */
|
||||||
|
int git_blame__get_origin(
|
||||||
|
git_blame__origin **out,
|
||||||
|
git_blame *blame,
|
||||||
|
git_commit *commit,
|
||||||
|
const char *path)
|
||||||
|
{
|
||||||
|
git_blame__entry *e;
|
||||||
|
|
||||||
|
for (e = blame->ent; e; e = e->next) {
|
||||||
|
if (e->suspect->commit == commit && !strcmp(e->suspect->path, path)) {
|
||||||
|
*out = origin_incref(e->suspect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return make_origin(out, commit, path);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct blame_chunk_cb_data {
|
||||||
git_blame *blame;
|
git_blame *blame;
|
||||||
git_blame__origin *target;
|
git_blame__origin *target;
|
||||||
git_blame__origin *parent;
|
git_blame__origin *parent;
|
||||||
long tlno;
|
long tlno;
|
||||||
long plno;
|
long plno;
|
||||||
};
|
}blame_chunk_cb_data;
|
||||||
|
|
||||||
static bool same_suspect(git_blame__origin *a, git_blame__origin *b)
|
static bool same_suspect(git_blame__origin *a, git_blame__origin *b)
|
||||||
{
|
{
|
||||||
@ -88,10 +107,10 @@ static int find_last_in_target(git_blame *blame, git_blame__origin *target)
|
|||||||
* line plno corresponds to e's line tlno.
|
* line plno corresponds to e's line tlno.
|
||||||
*
|
*
|
||||||
* <---- e ----->
|
* <---- e ----->
|
||||||
* <------>
|
* <------> (entirely within)
|
||||||
* <------------>
|
* <------------> (overlaps after)
|
||||||
* <------------>
|
* <------------> (overlaps before)
|
||||||
* <------------------>
|
* <------------------> (overlaps both)
|
||||||
*
|
*
|
||||||
* Split e into potentially three parts; before this chunk, the chunk
|
* Split e into potentially three parts; before this chunk, the chunk
|
||||||
* to be blamed for the parent, and after that portion.
|
* to be blamed for the parent, and after that portion.
|
||||||
@ -237,7 +256,13 @@ static void decref_split(git_blame__entry *split)
|
|||||||
* Helper for blame_chunk(). blame_entry e is known to overlap with the patch
|
* Helper for blame_chunk(). blame_entry e is known to overlap with the patch
|
||||||
* hunk; split it and pass blame to the parent.
|
* hunk; split it and pass blame to the parent.
|
||||||
*/
|
*/
|
||||||
static void blame_overlap(git_blame *blame, git_blame__entry *e, int tlno, int plno, int same, git_blame__origin *parent)
|
static void blame_overlap(
|
||||||
|
git_blame *blame,
|
||||||
|
git_blame__entry *e,
|
||||||
|
int tlno,
|
||||||
|
int plno,
|
||||||
|
int same,
|
||||||
|
git_blame__origin *parent)
|
||||||
{
|
{
|
||||||
git_blame__entry split[3] = {{0}};
|
git_blame__entry split[3] = {{0}};
|
||||||
|
|
||||||
@ -252,7 +277,13 @@ static void blame_overlap(git_blame *blame, git_blame__entry *e, int tlno, int p
|
|||||||
* e and its parent. Find and split the overlap, and pass blame to the
|
* e and its parent. Find and split the overlap, and pass blame to the
|
||||||
* overlapping part to the parent.
|
* overlapping part to the parent.
|
||||||
*/
|
*/
|
||||||
static void blame_chunk(git_blame *blame, int tlno, int plno, int same, git_blame__origin *target, git_blame__origin *parent)
|
static void blame_chunk(
|
||||||
|
git_blame *blame,
|
||||||
|
int tlno,
|
||||||
|
int plno,
|
||||||
|
int same,
|
||||||
|
git_blame__origin *target,
|
||||||
|
git_blame__origin *parent)
|
||||||
{
|
{
|
||||||
git_blame__entry *e;
|
git_blame__entry *e;
|
||||||
|
|
||||||
@ -267,21 +298,20 @@ static void blame_chunk(git_blame *blame, int tlno, int plno, int same, git_blam
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void blame_chunk_cb(long start_a, long count_a, long start_b, long count_b, void *data)
|
static int my_emit(
|
||||||
{
|
xdfenv_t *xe,
|
||||||
struct blame_chunk_cb_data *d = data;
|
xdchange_t *xscr,
|
||||||
blame_chunk(d->blame, d->tlno, d->plno, start_b, d->target, d->parent);
|
xdemitcb_t *ecb,
|
||||||
d->plno = start_a + count_a;
|
xdemitconf_t const *xecfg)
|
||||||
d->tlno = start_b + count_b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int my_emit_func(xdfenv_t *xe, xdchange_t *xscr, xdemitcb_t *ecb, xdemitconf_t const *xecfg)
|
|
||||||
{
|
{
|
||||||
xdchange_t *xch = xscr;
|
xdchange_t *xch = xscr;
|
||||||
GIT_UNUSED(xe);
|
GIT_UNUSED(xe);
|
||||||
GIT_UNUSED(xecfg);
|
GIT_UNUSED(xecfg);
|
||||||
while (xch) {
|
while (xch) {
|
||||||
blame_chunk_cb(xch->i1, xch->chg1, xch->i2, xch->chg2, ecb->priv);
|
blame_chunk_cb_data *d = ecb->priv;
|
||||||
|
blame_chunk(d->blame, d->tlno, d->plno, xch->i2, d->target, d->parent);
|
||||||
|
d->plno = xch->i1 + xch->chg1;
|
||||||
|
d->tlno = xch->i2 + xch->chg2;
|
||||||
xch = xch->next;
|
xch = xch->next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -311,26 +341,17 @@ static void trim_common_tail(mmfile_t *a, mmfile_t *b, long ctx)
|
|||||||
b->size -= trimmed - recovered;
|
b->size -= trimmed - recovered;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int xdi_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp, xdemitconf_t const *xecfg, xdemitcb_t *xecb)
|
static int diff_hunks(mmfile_t file_a, mmfile_t file_b, void *cb_data)
|
||||||
{
|
|
||||||
mmfile_t a = *mf1;
|
|
||||||
mmfile_t b = *mf2;
|
|
||||||
|
|
||||||
trim_common_tail(&a, &b, xecfg->ctxlen);
|
|
||||||
|
|
||||||
return xdl_diff(&a, &b, xpp, xecfg, xecb);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int diff_hunks(mmfile_t *file_a, mmfile_t *file_b, void *cb_data)
|
|
||||||
{
|
{
|
||||||
xpparam_t xpp = {0};
|
xpparam_t xpp = {0};
|
||||||
xdemitconf_t xecfg = {0};
|
xdemitconf_t xecfg = {0};
|
||||||
xdemitcb_t ecb = {0};
|
xdemitcb_t ecb = {0};
|
||||||
|
|
||||||
xecfg.emit_func = (void(*)(void))my_emit_func;
|
xecfg.emit_func = (void(*)(void))my_emit;
|
||||||
ecb.priv = cb_data;
|
ecb.priv = cb_data;
|
||||||
return xdi_diff(file_a, file_b, &xpp, &xecfg, &ecb);
|
|
||||||
|
trim_common_tail(&file_a, &file_b, 0);
|
||||||
|
return xdl_diff(&file_a, &file_b, &xpp, &xecfg, &ecb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fill_origin_blob(git_blame__origin *o, mmfile_t *file)
|
static void fill_origin_blob(git_blame__origin *o, mmfile_t *file)
|
||||||
@ -342,13 +363,14 @@ static void fill_origin_blob(git_blame__origin *o, mmfile_t *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pass_blame_to_parent(git_blame *blame,
|
static int pass_blame_to_parent(
|
||||||
git_blame__origin *target,
|
git_blame *blame,
|
||||||
git_blame__origin *parent)
|
git_blame__origin *target,
|
||||||
|
git_blame__origin *parent)
|
||||||
{
|
{
|
||||||
int last_in_target;
|
int last_in_target;
|
||||||
mmfile_t file_p, file_o;
|
mmfile_t file_p, file_o;
|
||||||
struct blame_chunk_cb_data d = { blame, target, parent, 0, 0 };
|
blame_chunk_cb_data d = { blame, target, parent, 0, 0 };
|
||||||
|
|
||||||
last_in_target = find_last_in_target(blame, target);
|
last_in_target = find_last_in_target(blame, target);
|
||||||
if (last_in_target < 0)
|
if (last_in_target < 0)
|
||||||
@ -357,7 +379,7 @@ static int pass_blame_to_parent(git_blame *blame,
|
|||||||
fill_origin_blob(parent, &file_p);
|
fill_origin_blob(parent, &file_p);
|
||||||
fill_origin_blob(target, &file_o);
|
fill_origin_blob(target, &file_o);
|
||||||
|
|
||||||
diff_hunks(&file_p, &file_o, &d);
|
diff_hunks(file_p, file_o, &d);
|
||||||
/* The reset (i.e. anything after tlno) are the same as the parent */
|
/* The reset (i.e. anything after tlno) are the same as the parent */
|
||||||
blame_chunk(blame, d.tlno, d.plno, last_in_target, target, parent);
|
blame_chunk(blame, d.tlno, d.plno, last_in_target, target, parent);
|
||||||
|
|
||||||
@ -370,7 +392,10 @@ static int paths_on_dup(void **old, void *new)
|
|||||||
git__free(new);
|
git__free(new);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
static git_blame__origin* find_origin(git_blame *blame, git_commit *parent,
|
|
||||||
|
static git_blame__origin* find_origin(
|
||||||
|
git_blame *blame,
|
||||||
|
git_commit *parent,
|
||||||
git_blame__origin *origin)
|
git_blame__origin *origin)
|
||||||
{
|
{
|
||||||
git_blame__origin *porigin = NULL;
|
git_blame__origin *porigin = NULL;
|
||||||
@ -395,7 +420,7 @@ static git_blame__origin* find_origin(git_blame *blame, git_commit *parent,
|
|||||||
|
|
||||||
if (!git_diff_num_deltas(difflist)) {
|
if (!git_diff_num_deltas(difflist)) {
|
||||||
/* No changes; copy data */
|
/* No changes; copy data */
|
||||||
get_origin(&porigin, blame, parent, origin->path);
|
git_blame__get_origin(&porigin, blame, parent, origin->path);
|
||||||
} else {
|
} else {
|
||||||
git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
|
git_diff_find_options findopts = GIT_DIFF_FIND_OPTIONS_INIT;
|
||||||
int i;
|
int i;
|
||||||
@ -418,7 +443,8 @@ static git_blame__origin* find_origin(git_blame *blame, git_commit *parent,
|
|||||||
if (git_vector_bsearch(NULL, &blame->paths, delta->new_file.path) != 0)
|
if (git_vector_bsearch(NULL, &blame->paths, delta->new_file.path) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
git_vector_insert_sorted(&blame->paths, (void*)git__strdup(delta->old_file.path), paths_on_dup);
|
git_vector_insert_sorted(&blame->paths, (void*)git__strdup(delta->old_file.path),
|
||||||
|
paths_on_dup);
|
||||||
make_origin(&porigin, parent, delta->old_file.path);
|
make_origin(&porigin, parent, delta->old_file.path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -440,8 +466,8 @@ static void pass_whole_blame(git_blame *blame,
|
|||||||
git_blame__entry *e;
|
git_blame__entry *e;
|
||||||
|
|
||||||
if (!porigin->blob)
|
if (!porigin->blob)
|
||||||
git_object_lookup((git_object**)&porigin->blob, blame->repository, git_blob_id(origin->blob),
|
git_object_lookup((git_object**)&porigin->blob, blame->repository,
|
||||||
GIT_OBJ_BLOB);
|
git_blob_id(origin->blob), GIT_OBJ_BLOB);
|
||||||
for (e=blame->ent; e; e=e->next) {
|
for (e=blame->ent; e; e=e->next) {
|
||||||
if (!same_suspect(e->suspect, origin))
|
if (!same_suspect(e->suspect, origin))
|
||||||
continue;
|
continue;
|
||||||
@ -454,25 +480,26 @@ static void pass_whole_blame(git_blame *blame,
|
|||||||
static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt)
|
static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt)
|
||||||
{
|
{
|
||||||
git_commit *commit = origin->commit;
|
git_commit *commit = origin->commit;
|
||||||
int i, num_sg;
|
int i, num_parents;
|
||||||
git_blame__origin *sg_buf[16];
|
git_blame__origin *sg_buf[16];
|
||||||
git_blame__origin *porigin, **sg_origin = sg_buf;
|
git_blame__origin *porigin, **sg_origin = sg_buf;
|
||||||
|
|
||||||
GIT_UNUSED(opt);
|
GIT_UNUSED(opt);
|
||||||
|
|
||||||
num_sg = git_commit_parentcount(commit);
|
num_parents = git_commit_parentcount(commit);
|
||||||
if (!git_oid_cmp(git_commit_id(commit), &blame->options.oldest_commit))
|
if (!git_oid_cmp(git_commit_id(commit), &blame->options.oldest_commit))
|
||||||
num_sg = 0;
|
/* Stop at oldest specified commit */
|
||||||
if (!num_sg) {
|
num_parents = 0;
|
||||||
|
if (!num_parents) {
|
||||||
git_oid_cpy(&blame->options.oldest_commit, git_commit_id(commit));
|
git_oid_cpy(&blame->options.oldest_commit, git_commit_id(commit));
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
else if (num_sg < (int)ARRAY_SIZE(sg_buf))
|
else if (num_parents < (int)ARRAY_SIZE(sg_buf))
|
||||||
memset(sg_buf, 0, sizeof(sg_buf));
|
memset(sg_buf, 0, sizeof(sg_buf));
|
||||||
else
|
else
|
||||||
sg_origin = git__calloc(num_sg, sizeof(*sg_origin));
|
sg_origin = git__calloc(num_parents, sizeof(*sg_origin));
|
||||||
|
|
||||||
for (i=0; i<num_sg; i++) {
|
for (i=0; i<num_parents; i++) {
|
||||||
git_commit *p;
|
git_commit *p;
|
||||||
int j, same;
|
int j, same;
|
||||||
|
|
||||||
@ -502,7 +529,8 @@ static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt
|
|||||||
origin_decref(porigin);
|
origin_decref(porigin);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<num_sg; i++) {
|
/* Standard blame */
|
||||||
|
for (i=0; i<num_parents; i++) {
|
||||||
git_blame__origin *porigin = sg_origin[i];
|
git_blame__origin *porigin = sg_origin[i];
|
||||||
if (!porigin)
|
if (!porigin)
|
||||||
continue;
|
continue;
|
||||||
@ -519,7 +547,7 @@ static void pass_blame(git_blame *blame, git_blame__origin *origin, uint32_t opt
|
|||||||
/* TODO: optionally find copies in parents' files */
|
/* TODO: optionally find copies in parents' files */
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
for (i=0; i<num_sg; i++)
|
for (i=0; i<num_parents; i++)
|
||||||
if (sg_origin[i])
|
if (sg_origin[i])
|
||||||
origin_decref(sg_origin[i]);
|
origin_decref(sg_origin[i]);
|
||||||
if (sg_origin != sg_buf)
|
if (sg_origin != sg_buf)
|
||||||
@ -528,28 +556,32 @@ finish:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Origin is refcounted and usually we keep the blob contents to be
|
* If two blame entries that are next to each other came from
|
||||||
* reused.
|
* contiguous lines in the same origin (i.e. <commit, path> pair),
|
||||||
|
* merge them together.
|
||||||
*/
|
*/
|
||||||
git_blame__origin *origin_incref(git_blame__origin *o)
|
static void coalesce(git_blame *blame)
|
||||||
{
|
{
|
||||||
if (o)
|
git_blame__entry *ent, *next;
|
||||||
o->refcnt++;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
void origin_decref(git_blame__origin *o)
|
for (ent=blame->ent; ent && (next = ent->next); ent = next) {
|
||||||
{
|
if (same_suspect(ent->suspect, next->suspect) &&
|
||||||
if (o && --o->refcnt <= 0) {
|
ent->guilty == next->guilty &&
|
||||||
if (o->previous)
|
ent->s_lno + ent->num_lines == next->s_lno)
|
||||||
origin_decref(o->previous);
|
{
|
||||||
git_blob_free(o->blob);
|
ent->num_lines += next->num_lines;
|
||||||
git_commit_free(o->commit);
|
ent->next = next->next;
|
||||||
git__free(o);
|
if (ent->next)
|
||||||
|
ent->next->prev = ent;
|
||||||
|
origin_decref(next->suspect);
|
||||||
|
git__free(next);
|
||||||
|
ent->score = 0;
|
||||||
|
next = ent; /* again */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void assign_blame(git_blame *blame, uint32_t opt)
|
void git_blame__like_git(git_blame *blame, uint32_t opt)
|
||||||
{
|
{
|
||||||
while (true) {
|
while (true) {
|
||||||
git_blame__entry *ent;
|
git_blame__entry *ent;
|
||||||
@ -577,26 +609,13 @@ void assign_blame(git_blame *blame, uint32_t opt)
|
|||||||
}
|
}
|
||||||
origin_decref(suspect);
|
origin_decref(suspect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
coalesce(blame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void coalesce(git_blame *blame)
|
void git_blame__free_entry(git_blame__entry *ent)
|
||||||
{
|
{
|
||||||
git_blame__entry *ent, *next;
|
if (!ent) return;
|
||||||
|
origin_decref(ent->suspect);
|
||||||
for (ent=blame->ent; ent && (next = ent->next); ent = next) {
|
git__free(ent);
|
||||||
if (same_suspect(ent->suspect, next->suspect) &&
|
|
||||||
ent->guilty == next->guilty &&
|
|
||||||
ent->s_lno + ent->num_lines == next->s_lno)
|
|
||||||
{
|
|
||||||
ent->num_lines += next->num_lines;
|
|
||||||
ent->next = next->next;
|
|
||||||
if (ent->next)
|
|
||||||
ent->next->prev = ent;
|
|
||||||
origin_decref(next->suspect);
|
|
||||||
git__free(next);
|
|
||||||
ent->score = 0;
|
|
||||||
next = ent; /* again */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,16 +1,21 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) the libgit2 contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* This file is part of libgit2, distributed under the GNU GPL v2 with
|
||||||
|
* a Linking Exception. For full terms see the included COPYING file.
|
||||||
|
*/
|
||||||
#ifndef INCLUDE_blame_git__
|
#ifndef INCLUDE_blame_git__
|
||||||
#define INCLUDE_blame_git__
|
#define INCLUDE_blame_git__
|
||||||
|
|
||||||
#include "git2.h"
|
|
||||||
#include "blame.h"
|
#include "blame.h"
|
||||||
#include "xdiff/xinclude.h"
|
#include "xdiff/xinclude.h"
|
||||||
|
|
||||||
int get_origin(git_blame__origin **out, git_blame *sb, git_commit *commit, const char *path);
|
int git_blame__get_origin(
|
||||||
int make_origin(git_blame__origin **out, git_commit *commit, const char *path);
|
git_blame__origin **out,
|
||||||
git_blame__origin *origin_incref(git_blame__origin *o);
|
git_blame *sb,
|
||||||
void origin_decref(git_blame__origin *o);
|
git_commit *commit,
|
||||||
void assign_blame(git_blame *sb, uint32_t flags);
|
const char *path);
|
||||||
void coalesce(git_blame *sb);
|
void git_blame__free_entry(git_blame__entry *ent);
|
||||||
|
void git_blame__like_git(git_blame *sb, uint32_t flags);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user