mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-12 21:09:04 +00:00
Clean up old methods, format long lines
Added back the line index. We'll need it later.
This commit is contained in:
parent
0a0f0558a4
commit
f0c9d8ba1c
89
src/blame.c
89
src/blame.c
@ -17,21 +17,20 @@
|
|||||||
#include "blame_git.h"
|
#include "blame_git.h"
|
||||||
|
|
||||||
|
|
||||||
static int hunk_search_cmp_helper(const void *key, size_t start_line, size_t num_lines)
|
static int hunk_byfinalline_search_cmp(const void *key, const void *entry)
|
||||||
{
|
{
|
||||||
uint32_t lineno = *(size_t*)key;
|
uint32_t lineno = *(size_t*)key;
|
||||||
if (lineno < start_line)
|
git_blame_hunk *hunk = (git_blame_hunk*)entry;
|
||||||
|
|
||||||
|
if (lineno < hunk->final_start_line_number)
|
||||||
return -1;
|
return -1;
|
||||||
if (lineno >= ((uint32_t)start_line + num_lines))
|
if (lineno >= hunk->final_start_line_number + hunk->lines_in_hunk)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
static int hunk_byfinalline_search_cmp(const void *key, const void *entry)
|
|
||||||
{
|
static int paths_cmp(const void *a, const void *b) { return git__strcmp((char*)a, (char*)b); }
|
||||||
git_blame_hunk *hunk = (git_blame_hunk*)entry;
|
static int hunk_cmp(const void *_a, const void *_b)
|
||||||
return hunk_search_cmp_helper(key, hunk->final_start_line_number, hunk->lines_in_hunk);
|
|
||||||
}
|
|
||||||
static int hunk_sort_cmp_by_start_line(const void *_a, const void *_b)
|
|
||||||
{
|
{
|
||||||
git_blame_hunk *a = (git_blame_hunk*)_a,
|
git_blame_hunk *a = (git_blame_hunk*)_a,
|
||||||
*b = (git_blame_hunk*)_b;
|
*b = (git_blame_hunk*)_b;
|
||||||
@ -49,7 +48,11 @@ static bool hunk_starts_at_or_after_line(git_blame_hunk *hunk, size_t line)
|
|||||||
return line <= hunk->final_start_line_number;
|
return line <= hunk->final_start_line_number;
|
||||||
}
|
}
|
||||||
|
|
||||||
static git_blame_hunk* new_hunk(uint16_t start, uint16_t lines, uint16_t orig_start, const char *path)
|
static git_blame_hunk* new_hunk(
|
||||||
|
uint16_t start,
|
||||||
|
uint16_t lines,
|
||||||
|
uint16_t orig_start,
|
||||||
|
const char *path)
|
||||||
{
|
{
|
||||||
git_blame_hunk *hunk = git__calloc(1, sizeof(git_blame_hunk));
|
git_blame_hunk *hunk = git__calloc(1, sizeof(git_blame_hunk));
|
||||||
if (!hunk) return NULL;
|
if (!hunk) return NULL;
|
||||||
@ -64,7 +67,11 @@ static git_blame_hunk* new_hunk(uint16_t start, uint16_t lines, uint16_t orig_st
|
|||||||
|
|
||||||
static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
|
static git_blame_hunk* dup_hunk(git_blame_hunk *hunk)
|
||||||
{
|
{
|
||||||
git_blame_hunk *newhunk = new_hunk(hunk->final_start_line_number, hunk->lines_in_hunk, hunk->orig_start_line_number, hunk->orig_path);
|
git_blame_hunk *newhunk = new_hunk(
|
||||||
|
hunk->final_start_line_number,
|
||||||
|
hunk->lines_in_hunk,
|
||||||
|
hunk->orig_start_line_number,
|
||||||
|
hunk->orig_path);
|
||||||
git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id);
|
git_oid_cpy(&newhunk->orig_commit_id, &hunk->orig_commit_id);
|
||||||
git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id);
|
git_oid_cpy(&newhunk->final_commit_id, &hunk->final_commit_id);
|
||||||
return newhunk;
|
return newhunk;
|
||||||
@ -78,7 +85,7 @@ static void free_hunk(git_blame_hunk *hunk)
|
|||||||
|
|
||||||
/* Starting with the hunk that includes start_line, shift all following hunks'
|
/* Starting with the hunk that includes start_line, shift all following hunks'
|
||||||
* final_start_line by shift_by lines */
|
* final_start_line by shift_by lines */
|
||||||
static void shift_hunks_by_final(git_vector *v, size_t start_line, int shift_by)
|
static void shift_hunks_by(git_vector *v, size_t start_line, int shift_by)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
@ -89,7 +96,7 @@ static void shift_hunks_by_final(git_vector *v, size_t start_line, int shift_by)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static int paths_cmp(const void *a, const void *b) { return git__strcmp((char*)a, (char*)b); }
|
|
||||||
git_blame* git_blame__alloc(
|
git_blame* git_blame__alloc(
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
git_blame_options opts,
|
git_blame_options opts,
|
||||||
@ -100,7 +107,7 @@ git_blame* git_blame__alloc(
|
|||||||
giterr_set_oom();
|
giterr_set_oom();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
git_vector_init(&gbr->hunks, 8, hunk_sort_cmp_by_start_line);
|
git_vector_init(&gbr->hunks, 8, hunk_cmp);
|
||||||
git_vector_init(&gbr->paths, 8, paths_cmp);
|
git_vector_init(&gbr->paths, 8, paths_cmp);
|
||||||
gbr->repository = repo;
|
gbr->repository = repo;
|
||||||
gbr->options = opts;
|
gbr->options = opts;
|
||||||
@ -125,6 +132,8 @@ void git_blame_free(git_blame *blame)
|
|||||||
git__free(path);
|
git__free(path);
|
||||||
git_vector_free(&blame->paths);
|
git_vector_free(&blame->paths);
|
||||||
|
|
||||||
|
git_array_clear(blame->line_index);
|
||||||
|
|
||||||
git__free((void*)blame->path);
|
git__free((void*)blame->path);
|
||||||
git_blob_free(blame->final_blob);
|
git_blob_free(blame->final_blob);
|
||||||
git__free(blame);
|
git__free(blame);
|
||||||
@ -205,21 +214,25 @@ static git_blame_hunk *split_hunk_in_vector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* To allow quick access to the contents of nth line in the
|
* Construct a list of char indices for where lines begin
|
||||||
* final image, prepare an index in the scoreboard.
|
* Adapted from core git:
|
||||||
|
* https://github.com/gitster/git/blob/be5c9fb9049ed470e7005f159bb923a5f4de1309/builtin/blame.c#L1760-L1789
|
||||||
*/
|
*/
|
||||||
static int prepare_lines(git_blame *blame)
|
static int index_blob_lines(git_blame *blame)
|
||||||
{
|
{
|
||||||
const char *buf = blame->final_buf;
|
const char *buf = blame->final_buf;
|
||||||
git_off_t len = blame->final_buf_size;
|
git_off_t len = blame->final_buf_size;
|
||||||
int num = 0, incomplete = 0, bol = 1;
|
int num = 0, incomplete = 0, bol = 1;
|
||||||
|
size_t *i;
|
||||||
|
|
||||||
if (len && buf[len-1] != '\n')
|
if (len && buf[len-1] != '\n')
|
||||||
incomplete++; /* incomplete line at the end */
|
incomplete++; /* incomplete line at the end */
|
||||||
while (len--) {
|
while (len--) {
|
||||||
if (bol) {
|
if (bol) {
|
||||||
|
i = git_array_alloc(blame->line_index);
|
||||||
|
GITERR_CHECK_ALLOC(i);
|
||||||
|
*i = buf - blame->final_buf;
|
||||||
bol = 0;
|
bol = 0;
|
||||||
}
|
}
|
||||||
if (*buf++ == '\n') {
|
if (*buf++ == '\n') {
|
||||||
@ -227,6 +240,9 @@ static int prepare_lines(git_blame *blame)
|
|||||||
bol = 1;
|
bol = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
i = git_array_alloc(blame->line_index);
|
||||||
|
GITERR_CHECK_ALLOC(i);
|
||||||
|
*i = buf - blame->final_buf;
|
||||||
blame->num_lines = num + incomplete;
|
blame->num_lines = num + incomplete;
|
||||||
return blame->num_lines;
|
return blame->num_lines;
|
||||||
}
|
}
|
||||||
@ -240,29 +256,31 @@ static git_blame_hunk* hunk_from_entry(git_blame__entry *e)
|
|||||||
return h;
|
return h;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int walk_and_mark(git_blame *blame)
|
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_blob *blob = NULL;
|
||||||
git_blame__origin *o;
|
git_blame__origin *o;
|
||||||
|
|
||||||
if ((error = git_commit_lookup(&blame->final, blame->repository, &blame->options.newest_commit)) < 0 ||
|
if ((error = git_commit_lookup(&blame->final, blame->repository,
|
||||||
(error = git_object_lookup_bypath((git_object**)&blob, (git_object*)blame->final, blame->path, GIT_OBJ_BLOB)) < 0)
|
&blame->options.newest_commit))
|
||||||
|
< 0 ||
|
||||||
|
(error = git_object_lookup_bypath((git_object**)&blob, (git_object*)blame->final,
|
||||||
|
blame->path, GIT_OBJ_BLOB))
|
||||||
|
< 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
blame->final_buf = git_blob_rawcontent(blob);
|
blame->final_buf = git_blob_rawcontent(blob);
|
||||||
blame->final_buf_size = git_blob_rawsize(blob);
|
blame->final_buf_size = git_blob_rawsize(blob);
|
||||||
if ((error = get_origin(&o, blame, blame->final, blame->path)) < 0)
|
if ((error = get_origin(&o, blame, blame->final, blame->path)) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
ent = git__calloc(1, sizeof(*ent));
|
ent = git__calloc(1, sizeof(git_blame__entry));
|
||||||
ent->num_lines = prepare_lines(blame);
|
ent->num_lines = index_blob_lines(blame);
|
||||||
ent->lno = blame->options.min_line - 1;
|
ent->lno = blame->options.min_line - 1;
|
||||||
ent->num_lines = ent->num_lines - blame->options.min_line + 1;
|
ent->num_lines = ent->num_lines - blame->options.min_line + 1;
|
||||||
if (blame->options.max_line > 0) {
|
if (blame->options.max_line > 0)
|
||||||
ent->num_lines = blame->options.max_line - blame->options.min_line + 1;
|
ent->num_lines = blame->options.max_line - blame->options.min_line + 1;
|
||||||
}
|
|
||||||
ent->s_lno = ent->lno;
|
ent->s_lno = ent->lno;
|
||||||
ent->suspect = o;
|
ent->suspect = o;
|
||||||
|
|
||||||
@ -275,11 +293,10 @@ static int walk_and_mark(git_blame *blame)
|
|||||||
cleanup:
|
cleanup:
|
||||||
for (ent = blame->ent; ent; ) {
|
for (ent = blame->ent; ent; ) {
|
||||||
git_blame__entry *e = ent->next;
|
git_blame__entry *e = ent->next;
|
||||||
git_blame__origin *o = ent->suspect;
|
|
||||||
|
|
||||||
git_vector_insert(&blame->hunks, hunk_from_entry(ent));
|
git_vector_insert(&blame->hunks, hunk_from_entry(ent));
|
||||||
|
|
||||||
origin_decref(o);
|
origin_decref(ent->suspect);
|
||||||
git__free(ent);
|
git__free(ent);
|
||||||
ent = e;
|
ent = e;
|
||||||
}
|
}
|
||||||
@ -288,6 +305,10 @@ cleanup:
|
|||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************************
|
||||||
|
* File blaming
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
static int load_blob(git_blame *blame, git_repository *repo, git_oid *commit_id, const char *path)
|
static int load_blob(git_blame *blame, git_repository *repo, git_oid *commit_id, const char *path)
|
||||||
{
|
{
|
||||||
int retval = -1;
|
int retval = -1;
|
||||||
@ -309,10 +330,6 @@ cleanup:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* File blaming
|
|
||||||
******************************************************************************/
|
|
||||||
|
|
||||||
int git_blame_file(
|
int git_blame_file(
|
||||||
git_blame **out,
|
git_blame **out,
|
||||||
git_repository *repo,
|
git_repository *repo,
|
||||||
@ -332,7 +349,7 @@ int git_blame_file(
|
|||||||
if ((error = load_blob(blame, repo, &normOptions.newest_commit, path)) < 0)
|
if ((error = load_blob(blame, repo, &normOptions.newest_commit, path)) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
if ((error = walk_and_mark(blame)) < 0)
|
if ((error = blame_internal(blame)) < 0)
|
||||||
goto on_error;
|
goto on_error;
|
||||||
|
|
||||||
*out = blame;
|
*out = blame;
|
||||||
@ -407,10 +424,10 @@ static int buffer_line_cb(
|
|||||||
hunk_ends_at_or_before_line(blame->current_hunk, blame->current_diff_line)) {
|
hunk_ends_at_or_before_line(blame->current_hunk, blame->current_diff_line)) {
|
||||||
/* Append to the current buffer-blame hunk */
|
/* Append to the current buffer-blame hunk */
|
||||||
blame->current_hunk->lines_in_hunk++;
|
blame->current_hunk->lines_in_hunk++;
|
||||||
shift_hunks_by_final(&blame->hunks, blame->current_diff_line+1, 1);
|
shift_hunks_by(&blame->hunks, blame->current_diff_line+1, 1);
|
||||||
} else {
|
} else {
|
||||||
/* Create a new buffer-blame hunk with this line */
|
/* Create a new buffer-blame hunk with this line */
|
||||||
shift_hunks_by_final(&blame->hunks, blame->current_diff_line, 1);
|
shift_hunks_by(&blame->hunks, blame->current_diff_line, 1);
|
||||||
blame->current_hunk = new_hunk(blame->current_diff_line, 1, 0, blame->path);
|
blame->current_hunk = new_hunk(blame->current_diff_line, 1, 0, blame->path);
|
||||||
git_vector_insert_sorted(&blame->hunks, blame->current_hunk, NULL);
|
git_vector_insert_sorted(&blame->hunks, blame->current_hunk, NULL);
|
||||||
}
|
}
|
||||||
@ -430,7 +447,7 @@ static int buffer_line_cb(
|
|||||||
blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byindex(blame, i);
|
blame->current_hunk = (git_blame_hunk*)git_blame_get_hunk_byindex(blame, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
shift_hunks_by_final(&blame->hunks, shift_base, -1);
|
shift_hunks_by(&blame->hunks, shift_base, -1);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -72,6 +72,7 @@ struct git_blame {
|
|||||||
git_vector paths;
|
git_vector paths;
|
||||||
|
|
||||||
git_blob *final_blob;
|
git_blob *final_blob;
|
||||||
|
git_array_t(size_t) line_index;
|
||||||
|
|
||||||
size_t current_diff_line;
|
size_t current_diff_line;
|
||||||
git_blame_hunk *current_hunk;
|
git_blame_hunk *current_hunk;
|
||||||
|
Loading…
Reference in New Issue
Block a user