From 9ebb5a3ff31a58a25714fbc98704b0fda0982cdb Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 18 Feb 2015 22:53:40 -0500 Subject: merge: merge iterators --- src/merge.c | 86 +++++++++++++++++++++++++++++++++----------- src/merge.h | 18 +++++++--- tests/merge/trees/treediff.c | 14 +++++++- 3 files changed, 93 insertions(+), 25 deletions(-) diff --git a/src/merge.c b/src/merge.c index bd676aacf..5e7727429 100644 --- a/src/merge.c +++ b/src/merge.c @@ -1451,11 +1451,11 @@ static int merge_diff_list_insert_unmodified( int git_merge_diff_list__find_differences( git_merge_diff_list *diff_list, - const git_tree *ancestor_tree, - const git_tree *our_tree, - const git_tree *their_tree) + git_iterator *ancestor_iter, + git_iterator *our_iter, + git_iterator *their_iter) { - git_iterator *iterators[3] = {0}; + git_iterator *iterators[3] = { ancestor_iter, our_iter, their_iter }; const git_index_entry *items[3] = {0}, *best_cur_item, *cur_items[3]; git_vector_cmp entry_compare = git_index_entry_cmp; struct merge_diff_df_data df_data = {0}; @@ -1463,12 +1463,7 @@ int git_merge_diff_list__find_differences( size_t i, j; int error = 0; - assert(diff_list && (our_tree || their_tree)); - - if ((error = git_iterator_for_tree(&iterators[TREE_IDX_ANCESTOR], (git_tree *)ancestor_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 || - (error = git_iterator_for_tree(&iterators[TREE_IDX_OURS], (git_tree *)our_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 || - (error = git_iterator_for_tree(&iterators[TREE_IDX_THEIRS], (git_tree *)their_tree, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0) - goto done; + assert(diff_list && (our_iter || their_iter)); /* Set up the iterators */ for (i = 0; i < 3; i++) { @@ -1544,9 +1539,6 @@ int git_merge_diff_list__find_differences( } done: - for (i = 0; i < 3; i++) - git_iterator_free(iterators[i]); - if (error == GIT_ITEROVER) error = 0; @@ -1757,14 +1749,28 @@ on_error: return error; } -int git_merge_trees( +static git_iterator *iterator_given_or_empty(git_iterator **empty, git_iterator *given) +{ + if (given) + return given; + + if (git_iterator_for_nothing(empty, GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL) < 0) + return NULL; + + return *empty; +} + +int git_merge__iterators( git_index **out, git_repository *repo, - const git_tree *ancestor_tree, - const git_tree *our_tree, - const git_tree *their_tree, + git_iterator *ancestor_iter, + git_iterator *our_iter, + git_iterator *theirs_iter, const git_merge_options *given_opts) { + git_iterator *empty_ancestor = NULL, + *empty_ours = NULL, + *empty_theirs = NULL; git_merge_diff_list *diff_list; git_merge_options opts; git_merge_diff *conflict; @@ -1772,11 +1778,12 @@ int git_merge_trees( size_t i; int error = 0; - assert(out && repo && (our_tree || their_tree)); + assert(out && repo); *out = NULL; - GITERR_CHECK_VERSION(given_opts, GIT_MERGE_OPTIONS_VERSION, "git_merge_options"); + GITERR_CHECK_VERSION( + given_opts, GIT_MERGE_OPTIONS_VERSION, "git_merge_options"); if ((error = merge_normalize_opts(repo, &opts, given_opts)) < 0) return error; @@ -1784,7 +1791,12 @@ int git_merge_trees( diff_list = git_merge_diff_list__alloc(repo); GITERR_CHECK_ALLOC(diff_list); - if ((error = git_merge_diff_list__find_differences(diff_list, ancestor_tree, our_tree, their_tree)) < 0 || + ancestor_iter = iterator_given_or_empty(&empty_ancestor, ancestor_iter); + our_iter = iterator_given_or_empty(&empty_ours, our_iter); + theirs_iter = iterator_given_or_empty(&empty_theirs, theirs_iter); + + if ((error = git_merge_diff_list__find_differences( + diff_list, ancestor_iter, our_iter, theirs_iter)) < 0 || (error = git_merge_diff_list__find_renames(repo, diff_list, &opts)) < 0) goto done; @@ -1808,10 +1820,44 @@ int git_merge_trees( done: git_merge_diff_list__free(diff_list); + git_iterator_free(empty_ancestor); + git_iterator_free(empty_ours); + git_iterator_free(empty_theirs); + + return error; +} + +int git_merge_trees( + git_index **out, + git_repository *repo, + const git_tree *ancestor_tree, + const git_tree *our_tree, + const git_tree *their_tree, + const git_merge_options *merge_opts) +{ + git_iterator *ancestor_iter = NULL, *our_iter = NULL, *their_iter = NULL; + int error; + + if ((error = git_iterator_for_tree(&ancestor_iter, (git_tree *)ancestor_tree, + GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 || + (error = git_iterator_for_tree(&our_iter, (git_tree *)our_tree, + GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0 || + (error = git_iterator_for_tree(&their_iter, (git_tree *)their_tree, + GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)) < 0) + goto done; + + error = git_merge__iterators( + out, repo, ancestor_iter, our_iter, their_iter, merge_opts); + +done: + git_iterator_free(ancestor_iter); + git_iterator_free(our_iter); + git_iterator_free(their_iter); return error; } + int git_merge_commits( git_index **out, git_repository *repo, diff --git a/src/merge.h b/src/merge.h index fe4505f8b..3caf617c6 100644 --- a/src/merge.h +++ b/src/merge.h @@ -10,6 +10,7 @@ #include "vector.h" #include "commit_list.h" #include "pool.h" +#include "iterator.h" #include "git2/merge.h" #include "git2/types.h" @@ -121,10 +122,11 @@ int git_merge__bases_many( git_merge_diff_list *git_merge_diff_list__alloc(git_repository *repo); -int git_merge_diff_list__find_differences(git_merge_diff_list *merge_diff_list, - const git_tree *ancestor_tree, - const git_tree *ours_tree, - const git_tree *theirs_tree); +int git_merge_diff_list__find_differences( + git_merge_diff_list *merge_diff_list, + git_iterator *ancestor_iterator, + git_iterator *ours_iter, + git_iterator *theirs_iter); int git_merge_diff_list__find_renames(git_repository *repo, git_merge_diff_list *merge_diff_list, const git_merge_options *opts); @@ -138,6 +140,14 @@ int git_merge__setup( const git_annotated_commit *heads[], size_t heads_len); +int git_merge__iterators( + git_index **out, + git_repository *repo, + git_iterator *ancestor_iter, + git_iterator *our_iter, + git_iterator *their_iter, + const git_merge_options *given_opts); + int git_merge__check_result(git_repository *repo, git_index *index_new); int git_merge__append_conflicts_to_merge_msg(git_repository *repo, git_index *index); diff --git a/tests/merge/trees/treediff.c b/tests/merge/trees/treediff.c index eea651de0..b96c4c4db 100644 --- a/tests/merge/trees/treediff.c +++ b/tests/merge/trees/treediff.c @@ -43,6 +43,7 @@ static void test_find_differences( git_merge_diff_list *merge_diff_list = git_merge_diff_list__alloc(repo); git_oid ancestor_oid, ours_oid, theirs_oid; git_tree *ancestor_tree, *ours_tree, *theirs_tree; + git_iterator *ancestor_iter, *ours_iter, *theirs_iter; git_merge_options opts = GIT_MERGE_OPTIONS_INIT; opts.tree_flags |= GIT_MERGE_TREE_FIND_RENAMES; @@ -66,7 +67,14 @@ static void test_find_differences( cl_git_pass(git_tree_lookup(&ours_tree, repo, &ours_oid)); cl_git_pass(git_tree_lookup(&theirs_tree, repo, &theirs_oid)); - cl_git_pass(git_merge_diff_list__find_differences(merge_diff_list, ancestor_tree, ours_tree, theirs_tree)); + cl_git_pass(git_iterator_for_tree(&ancestor_iter, ancestor_tree, + GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)); + cl_git_pass(git_iterator_for_tree(&ours_iter, ours_tree, + GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)); + cl_git_pass(git_iterator_for_tree(&theirs_iter, theirs_tree, + GIT_ITERATOR_DONT_IGNORE_CASE, NULL, NULL)); + + cl_git_pass(git_merge_diff_list__find_differences(merge_diff_list, ancestor_iter, ours_iter, theirs_iter)); cl_git_pass(git_merge_diff_list__find_renames(repo, merge_diff_list, &opts)); /* @@ -77,6 +85,10 @@ static void test_find_differences( cl_assert(merge_test_merge_conflicts(&merge_diff_list->conflicts, treediff_conflict_data, treediff_conflict_data_len)); + git_iterator_free(ancestor_iter); + git_iterator_free(ours_iter); + git_iterator_free(theirs_iter); + git_tree_free(ancestor_tree); git_tree_free(ours_tree); git_tree_free(theirs_tree); -- cgit v1.2.1