summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVicent Marti <vicent@github.com>2015-10-23 13:37:02 +0200
committerVicent Marti <vicent@github.com>2015-10-23 13:37:02 +0200
commit7c0c21c3f35dc7b5667a9c16d4e3a2ddf1901f30 (patch)
tree444c214b32d248e4452638478716f883b87bc22a
parentdc2cf3eb1a71700a064720618ed5df267cffcbac (diff)
parent8683d31f080eb12fe769ab2363165ec17562c840 (diff)
downloadlibgit2-7c0c21c3f35dc7b5667a9c16d4e3a2ddf1901f30.tar.gz
Merge pull request #3482 from ethomson/merge_fail_on_conflict
merge: add GIT_MERGE_TREE_FAIL_ON_CONFLICT
-rw-r--r--include/git2/errors.h1
-rw-r--r--include/git2/merge.h7
-rw-r--r--src/merge.c9
-rw-r--r--tests/merge/merge_helpers.c9
-rw-r--r--tests/merge/trees/commits.c18
5 files changed, 38 insertions, 6 deletions
diff --git a/include/git2/errors.h b/include/git2/errors.h
index 4698366d8..1b528cf25 100644
--- a/include/git2/errors.h
+++ b/include/git2/errors.h
@@ -49,6 +49,7 @@ typedef enum {
GIT_EINVALID = -21, /**< Invalid operation or input */
GIT_EUNCOMMITTED = -22, /**< Uncommitted changes in index prevented operation */
GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */
+ GIT_EMERGECONFLICT = -24, /**< A merge conflict exists and cannot continue */
GIT_PASSTHROUGH = -30, /**< Internal only */
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */
diff --git a/include/git2/merge.h b/include/git2/merge.h
index 5fef452b9..ced9e51ff 100644
--- a/include/git2/merge.h
+++ b/include/git2/merge.h
@@ -72,6 +72,13 @@ typedef enum {
* the ability to merge between a modified and renamed file.
*/
GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
+
+ /**
+ * If a conflict occurs, exit immediately instead of attempting to
+ * continue resolving conflicts. The merge operation will fail with
+ * GIT_EMERGECONFLICT and no index will be returned.
+ */
+ GIT_MERGE_TREE_FAIL_ON_CONFLICT = (1 << 1),
} git_merge_tree_flag_t;
/**
diff --git a/src/merge.c b/src/merge.c
index 930457bdb..3bed0fd3b 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -1701,8 +1701,15 @@ int git_merge__iterators(
if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor, opts.file_flags)) < 0)
goto done;
- if (!resolved)
+ if (!resolved) {
+ if ((opts.tree_flags & GIT_MERGE_TREE_FAIL_ON_CONFLICT)) {
+ giterr_set(GITERR_MERGE, "merge conflicts exist");
+ error = GIT_EMERGECONFLICT;
+ goto done;
+ }
+
git_vector_insert(&diff_list->conflicts, conflict);
+ }
}
if (!given_opts || !given_opts->metric)
diff --git a/tests/merge/merge_helpers.c b/tests/merge/merge_helpers.c
index f81471424..986a365db 100644
--- a/tests/merge/merge_helpers.c
+++ b/tests/merge/merge_helpers.c
@@ -40,7 +40,7 @@ int merge_trees_from_branches(
cl_git_pass(git_commit_tree(&our_tree, our_commit));
cl_git_pass(git_commit_tree(&their_tree, their_commit));
- cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts));
+ error = git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts);
git_buf_free(&branch_buf);
git_tree_free(our_tree);
@@ -50,7 +50,7 @@ int merge_trees_from_branches(
git_commit_free(their_commit);
git_commit_free(ancestor_commit);
- return 0;
+ return error;
}
int merge_commits_from_branches(
@@ -61,6 +61,7 @@ int merge_commits_from_branches(
git_commit *our_commit, *their_commit;
git_oid our_oid, their_oid;
git_buf branch_buf = GIT_BUF_INIT;
+ int error;
git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name);
cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
@@ -71,13 +72,13 @@ int merge_commits_from_branches(
cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr));
cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid));
- cl_git_pass(git_merge_commits(index, repo, our_commit, their_commit, opts));
+ error = git_merge_commits(index, repo, our_commit, their_commit, opts);
git_buf_free(&branch_buf);
git_commit_free(our_commit);
git_commit_free(their_commit);
- return 0;
+ return error;
}
int merge_branches(git_repository *repo,
diff --git a/tests/merge/trees/commits.c b/tests/merge/trees/commits.c
index c4e470997..2e3c4578b 100644
--- a/tests/merge/trees/commits.c
+++ b/tests/merge/trees/commits.c
@@ -94,7 +94,6 @@ void test_merge_trees_commits__no_ancestor(void)
git_index_free(index);
}
-
void test_merge_trees_commits__df_conflict(void)
{
git_index *index;
@@ -129,3 +128,20 @@ void test_merge_trees_commits__df_conflict(void)
git_index_free(index);
}
+
+void test_merge_trees_commits__fail_on_conflict(void)
+{
+ git_index *index;
+ git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
+
+ opts.tree_flags |= GIT_MERGE_TREE_FAIL_ON_CONFLICT;
+
+ cl_git_fail_with(GIT_EMERGECONFLICT,
+ merge_trees_from_branches(&index, repo, "df_side1", "df_side2", &opts));
+
+ cl_git_fail_with(GIT_EMERGECONFLICT,
+ merge_commits_from_branches(&index, repo, "master", "unrelated", &opts));
+ cl_git_fail_with(GIT_EMERGECONFLICT,
+ merge_commits_from_branches(&index, repo, "master", "branch", &opts));
+}
+