mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-03 00:43:41 +00:00
More tests and fixed for merging reversed diffs
There were a lot more cases to deal with to make sure that our merged (i.e. workdir-to-tree-to-index) diffs were matching the output of core Git.
This commit is contained in:
parent
a5c16f3cfb
commit
e7c85120ea
@ -46,7 +46,6 @@ fail:
|
||||
}
|
||||
|
||||
static git_diff_delta *diff_delta__merge_like_cgit(
|
||||
uint16_t flags,
|
||||
const git_diff_delta *a,
|
||||
const git_diff_delta *b,
|
||||
git_pool *pool)
|
||||
@ -99,15 +98,46 @@ static git_diff_delta *diff_delta__merge_like_cgit(
|
||||
return dup;
|
||||
}
|
||||
|
||||
int git_diff_merge(
|
||||
git_diff *onto,
|
||||
const git_diff *from)
|
||||
static git_diff_delta *diff_delta__merge_like_cgit_reversed(
|
||||
const git_diff_delta *a,
|
||||
const git_diff_delta *b,
|
||||
git_pool *pool)
|
||||
{
|
||||
git_diff_delta *dup;
|
||||
|
||||
/* reversed version of above logic */
|
||||
|
||||
if (a->status == GIT_DELTA_UNMODIFIED)
|
||||
return diff_delta__dup(b, pool);
|
||||
|
||||
if ((dup = diff_delta__dup(a, pool)) == NULL)
|
||||
return NULL;
|
||||
|
||||
if (b->status == GIT_DELTA_UNMODIFIED || b->status == GIT_DELTA_UNTRACKED)
|
||||
return dup;
|
||||
|
||||
if (dup->status == GIT_DELTA_DELETED) {
|
||||
if (b->status == GIT_DELTA_ADDED)
|
||||
dup->status = GIT_DELTA_UNMODIFIED;
|
||||
} else {
|
||||
dup->status = b->status;
|
||||
}
|
||||
|
||||
git_oid_cpy(&dup->old_file.oid, &b->old_file.oid);
|
||||
dup->old_file.mode = b->old_file.mode;
|
||||
dup->old_file.size = b->old_file.size;
|
||||
dup->old_file.flags = b->old_file.flags;
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
int git_diff_merge(git_diff *onto, const git_diff *from)
|
||||
{
|
||||
int error = 0;
|
||||
git_pool onto_pool;
|
||||
git_vector onto_new;
|
||||
git_diff_delta *delta;
|
||||
bool ignore_case = false;
|
||||
bool ignore_case, reversed;
|
||||
unsigned int i, j;
|
||||
|
||||
assert(onto && from);
|
||||
@ -115,11 +145,11 @@ int git_diff_merge(
|
||||
if (!from->deltas.length)
|
||||
return 0;
|
||||
|
||||
if ((onto->opts.flags & GIT_DIFF_IGNORE_CASE) !=
|
||||
(from->opts.flags & GIT_DIFF_IGNORE_CASE) ||
|
||||
(onto->opts.flags & GIT_DIFF_REVERSE) !=
|
||||
(from->opts.flags & GIT_DIFF_REVERSE))
|
||||
{
|
||||
ignore_case = ((onto->opts.flags & GIT_DIFF_IGNORE_CASE) != 0);
|
||||
reversed = ((onto->opts.flags & GIT_DIFF_REVERSE) != 0);
|
||||
|
||||
if (ignore_case != ((from->opts.flags & GIT_DIFF_IGNORE_CASE) != 0) ||
|
||||
reversed != ((from->opts.flags & GIT_DIFF_REVERSE) != 0)) {
|
||||
giterr_set(GITERR_INVALID,
|
||||
"Attempt to merge diffs created with conflicting options");
|
||||
return -1;
|
||||
@ -130,8 +160,6 @@ int git_diff_merge(
|
||||
git_pool_init(&onto_pool, 1, 0) < 0)
|
||||
return -1;
|
||||
|
||||
ignore_case = ((onto->opts.flags & GIT_DIFF_IGNORE_CASE) != 0);
|
||||
|
||||
for (i = 0, j = 0; i < onto->deltas.length || j < from->deltas.length; ) {
|
||||
git_diff_delta *o = GIT_VECTOR_GET(&onto->deltas, i);
|
||||
const git_diff_delta *f = GIT_VECTOR_GET(&from->deltas, j);
|
||||
@ -145,8 +173,9 @@ int git_diff_merge(
|
||||
delta = diff_delta__dup(f, &onto_pool);
|
||||
j++;
|
||||
} else {
|
||||
delta = diff_delta__merge_like_cgit(
|
||||
onto->opts.flags, o, f, &onto_pool);
|
||||
delta = reversed ?
|
||||
diff_delta__merge_like_cgit_reversed(o, f, &onto_pool) :
|
||||
diff_delta__merge_like_cgit(o, f, &onto_pool);
|
||||
i++;
|
||||
j++;
|
||||
}
|
||||
|
@ -196,6 +196,38 @@ void test_diff_workdir__to_tree(void)
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* Let's try that once more with a reversed diff */
|
||||
|
||||
opts.flags |= GIT_DIFF_REVERSE;
|
||||
|
||||
cl_git_pass(git_diff_tree_to_index(&diff, g_repo, b, NULL, &opts));
|
||||
cl_git_pass(git_diff_index_to_workdir(&diff2, g_repo, NULL, &opts));
|
||||
cl_git_pass(git_diff_merge(diff, diff2));
|
||||
git_diff_free(diff2);
|
||||
|
||||
memset(&exp, 0, sizeof(exp));
|
||||
|
||||
cl_git_pass(git_diff_foreach(
|
||||
diff, diff_file_cb, diff_hunk_cb, diff_line_cb, &exp));
|
||||
|
||||
cl_assert_equal_i(16, exp.files);
|
||||
cl_assert_equal_i(5, exp.file_status[GIT_DELTA_DELETED]);
|
||||
cl_assert_equal_i(4, exp.file_status[GIT_DELTA_ADDED]);
|
||||
cl_assert_equal_i(3, exp.file_status[GIT_DELTA_MODIFIED]);
|
||||
cl_assert_equal_i(1, exp.file_status[GIT_DELTA_IGNORED]);
|
||||
cl_assert_equal_i(3, exp.file_status[GIT_DELTA_UNTRACKED]);
|
||||
|
||||
cl_assert_equal_i(12, exp.hunks);
|
||||
|
||||
cl_assert_equal_i(19, exp.lines);
|
||||
cl_assert_equal_i(3, exp.line_ctxt);
|
||||
cl_assert_equal_i(12, exp.line_dels);
|
||||
cl_assert_equal_i(4, exp.line_adds);
|
||||
|
||||
git_diff_free(diff);
|
||||
|
||||
/* all done now */
|
||||
|
||||
git_tree_free(a);
|
||||
git_tree_free(b);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user