mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 01:58:32 +00:00

In the process of adding tests for the max file size threshold (which treats files over a certain size as binary) there seem to be a number of problems in the new code with detecting binaries. This should fix those up, as well as add a test for the file size threshold stuff. Also, this un-deprecates `GIT_DIFF_LINE_ADD_EOFNL`, since I finally found a legitimate situation where it would be returned.
176 lines
3.5 KiB
C
176 lines
3.5 KiB
C
#include "clar_libgit2.h"
|
|
#include "diff_helpers.h"
|
|
|
|
git_tree *resolve_commit_oid_to_tree(
|
|
git_repository *repo,
|
|
const char *partial_oid)
|
|
{
|
|
size_t len = strlen(partial_oid);
|
|
git_oid oid;
|
|
git_object *obj = NULL;
|
|
git_tree *tree = NULL;
|
|
|
|
if (git_oid_fromstrn(&oid, partial_oid, len) == 0)
|
|
git_object_lookup_prefix(&obj, repo, &oid, len, GIT_OBJ_ANY);
|
|
cl_assert(obj);
|
|
if (git_object_type(obj) == GIT_OBJ_TREE)
|
|
return (git_tree *)obj;
|
|
cl_assert(git_object_type(obj) == GIT_OBJ_COMMIT);
|
|
cl_git_pass(git_commit_tree(&tree, (git_commit *)obj));
|
|
git_object_free(obj);
|
|
return tree;
|
|
}
|
|
|
|
int diff_file_fn(
|
|
void *cb_data,
|
|
git_diff_delta *delta,
|
|
float progress)
|
|
{
|
|
diff_expects *e = cb_data;
|
|
|
|
GIT_UNUSED(progress);
|
|
|
|
if (delta->binary)
|
|
e->at_least_one_of_them_is_binary = true;
|
|
|
|
e->files++;
|
|
switch (delta->status) {
|
|
case GIT_DELTA_ADDED: e->file_adds++; break;
|
|
case GIT_DELTA_DELETED: e->file_dels++; break;
|
|
case GIT_DELTA_MODIFIED: e->file_mods++; break;
|
|
case GIT_DELTA_IGNORED: e->file_ignored++; break;
|
|
case GIT_DELTA_UNTRACKED: e->file_untracked++; break;
|
|
case GIT_DELTA_UNMODIFIED: e->file_unmodified++; break;
|
|
default: break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int diff_hunk_fn(
|
|
void *cb_data,
|
|
git_diff_delta *delta,
|
|
git_diff_range *range,
|
|
const char *header,
|
|
size_t header_len)
|
|
{
|
|
diff_expects *e = cb_data;
|
|
|
|
GIT_UNUSED(delta);
|
|
GIT_UNUSED(header);
|
|
GIT_UNUSED(header_len);
|
|
|
|
e->hunks++;
|
|
e->hunk_old_lines += range->old_lines;
|
|
e->hunk_new_lines += range->new_lines;
|
|
return 0;
|
|
}
|
|
|
|
int diff_line_fn(
|
|
void *cb_data,
|
|
git_diff_delta *delta,
|
|
git_diff_range *range,
|
|
char line_origin,
|
|
const char *content,
|
|
size_t content_len)
|
|
{
|
|
diff_expects *e = cb_data;
|
|
|
|
GIT_UNUSED(delta);
|
|
GIT_UNUSED(range);
|
|
GIT_UNUSED(content);
|
|
GIT_UNUSED(content_len);
|
|
|
|
e->lines++;
|
|
switch (line_origin) {
|
|
case GIT_DIFF_LINE_CONTEXT:
|
|
e->line_ctxt++;
|
|
break;
|
|
case GIT_DIFF_LINE_ADDITION:
|
|
e->line_adds++;
|
|
break;
|
|
case GIT_DIFF_LINE_ADD_EOFNL:
|
|
/* technically not a line add, but we'll count it as such */
|
|
e->line_adds++;
|
|
break;
|
|
case GIT_DIFF_LINE_DELETION:
|
|
e->line_dels++;
|
|
break;
|
|
case GIT_DIFF_LINE_DEL_EOFNL:
|
|
/* technically not a line delete, but we'll count it as such */
|
|
e->line_dels++;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int diff_foreach_via_iterator(
|
|
git_diff_list *diff,
|
|
void *data,
|
|
git_diff_file_fn file_cb,
|
|
git_diff_hunk_fn hunk_cb,
|
|
git_diff_data_fn line_cb)
|
|
{
|
|
int error;
|
|
git_diff_iterator *iter;
|
|
git_diff_delta *delta;
|
|
|
|
if ((error = git_diff_iterator_new(&iter, diff)) < 0)
|
|
return error;
|
|
|
|
while (!(error = git_diff_iterator_next_file(&delta, iter))) {
|
|
git_diff_range *range;
|
|
const char *hdr;
|
|
size_t hdr_len;
|
|
float progress = git_diff_iterator_progress(iter);
|
|
|
|
/* call file_cb for this file */
|
|
if (file_cb != NULL && file_cb(data, delta, progress) != 0)
|
|
goto abort;
|
|
|
|
if (!hunk_cb && !line_cb)
|
|
continue;
|
|
|
|
while (!(error = git_diff_iterator_next_hunk(
|
|
&range, &hdr, &hdr_len, iter))) {
|
|
char origin;
|
|
const char *line;
|
|
size_t line_len;
|
|
|
|
if (hunk_cb && hunk_cb(data, delta, range, hdr, hdr_len) != 0)
|
|
goto abort;
|
|
|
|
if (!line_cb)
|
|
continue;
|
|
|
|
while (!(error = git_diff_iterator_next_line(
|
|
&origin, &line, &line_len, iter))) {
|
|
|
|
if (line_cb(data, delta, range, origin, line, line_len) != 0)
|
|
goto abort;
|
|
}
|
|
|
|
if (error && error != GIT_ITEROVER)
|
|
goto done;
|
|
}
|
|
|
|
if (error && error != GIT_ITEROVER)
|
|
goto done;
|
|
}
|
|
|
|
done:
|
|
git_diff_iterator_free(iter);
|
|
|
|
if (error == GIT_ITEROVER)
|
|
error = 0;
|
|
|
|
return error;
|
|
|
|
abort:
|
|
git_diff_iterator_free(iter);
|
|
giterr_clear();
|
|
|
|
return GIT_EUSER;
|
|
}
|