Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/libgit2.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRussell Belfer <rb@github.com>2013-11-01 22:39:37 +0400
committerRussell Belfer <rb@github.com>2013-11-01 22:39:37 +0400
commite7c85120eab6c942d15c0f5ed3a2c8b6ec667617 (patch)
treed23cf50f11f9ee7bd9fabf6fc5b5fd92d1b53824 /src/diff_tform.c
parenta5c16f3cfb92f1129ef13124fc70147480141d69 (diff)
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.
Diffstat (limited to 'src/diff_tform.c')
-rw-r--r--src/diff_tform.c57
1 files changed, 43 insertions, 14 deletions
diff --git a/src/diff_tform.c b/src/diff_tform.c
index 0aec754a4..28a9cc70d 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -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++;
}