Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8683d31

Browse files
committed
merge: add GIT_MERGE_TREE_FAIL_ON_CONFLICT
Provide a new merge option, GIT_MERGE_TREE_FAIL_ON_CONFLICT, which will stop on the first conflict and fail the merge operation with GIT_EMERGECONFLICT.
1 parent dc2cf3e commit 8683d31

File tree

5 files changed

+38
-6
lines changed

5 files changed

+38
-6
lines changed

include/git2/errors.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef enum {
4949
GIT_EINVALID = -21, /**< Invalid operation or input */
5050
GIT_EUNCOMMITTED = -22, /**< Uncommitted changes in index prevented operation */
5151
GIT_EDIRECTORY = -23, /**< The operation is not valid for a directory */
52+
GIT_EMERGECONFLICT = -24, /**< A merge conflict exists and cannot continue */
5253

5354
GIT_PASSTHROUGH = -30, /**< Internal only */
5455
GIT_ITEROVER = -31, /**< Signals end of iteration with iterator */

include/git2/merge.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@ typedef enum {
7272
* the ability to merge between a modified and renamed file.
7373
*/
7474
GIT_MERGE_TREE_FIND_RENAMES = (1 << 0),
75+
76+
/**
77+
* If a conflict occurs, exit immediately instead of attempting to
78+
* continue resolving conflicts. The merge operation will fail with
79+
* GIT_EMERGECONFLICT and no index will be returned.
80+
*/
81+
GIT_MERGE_TREE_FAIL_ON_CONFLICT = (1 << 1),
7582
} git_merge_tree_flag_t;
7683

7784
/**

src/merge.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1701,8 +1701,15 @@ int git_merge__iterators(
17011701
if ((error = merge_conflict_resolve(&resolved, diff_list, conflict, opts.file_favor, opts.file_flags)) < 0)
17021702
goto done;
17031703

1704-
if (!resolved)
1704+
if (!resolved) {
1705+
if ((opts.tree_flags & GIT_MERGE_TREE_FAIL_ON_CONFLICT)) {
1706+
giterr_set(GITERR_MERGE, "merge conflicts exist");
1707+
error = GIT_EMERGECONFLICT;
1708+
goto done;
1709+
}
1710+
17051711
git_vector_insert(&diff_list->conflicts, conflict);
1712+
}
17061713
}
17071714

17081715
if (!given_opts || !given_opts->metric)

tests/merge/merge_helpers.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int merge_trees_from_branches(
4040
cl_git_pass(git_commit_tree(&our_tree, our_commit));
4141
cl_git_pass(git_commit_tree(&their_tree, their_commit));
4242

43-
cl_git_pass(git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts));
43+
error = git_merge_trees(index, repo, ancestor_tree, our_tree, their_tree, opts);
4444

4545
git_buf_free(&branch_buf);
4646
git_tree_free(our_tree);
@@ -50,7 +50,7 @@ int merge_trees_from_branches(
5050
git_commit_free(their_commit);
5151
git_commit_free(ancestor_commit);
5252

53-
return 0;
53+
return error;
5454
}
5555

5656
int merge_commits_from_branches(
@@ -61,6 +61,7 @@ int merge_commits_from_branches(
6161
git_commit *our_commit, *their_commit;
6262
git_oid our_oid, their_oid;
6363
git_buf branch_buf = GIT_BUF_INIT;
64+
int error;
6465

6566
git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours_name);
6667
cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr));
@@ -71,13 +72,13 @@ int merge_commits_from_branches(
7172
cl_git_pass(git_reference_name_to_id(&their_oid, repo, branch_buf.ptr));
7273
cl_git_pass(git_commit_lookup(&their_commit, repo, &their_oid));
7374

74-
cl_git_pass(git_merge_commits(index, repo, our_commit, their_commit, opts));
75+
error = git_merge_commits(index, repo, our_commit, their_commit, opts);
7576

7677
git_buf_free(&branch_buf);
7778
git_commit_free(our_commit);
7879
git_commit_free(their_commit);
7980

80-
return 0;
81+
return error;
8182
}
8283

8384
int merge_branches(git_repository *repo,

tests/merge/trees/commits.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@ void test_merge_trees_commits__no_ancestor(void)
9494
git_index_free(index);
9595
}
9696

97-
9897
void test_merge_trees_commits__df_conflict(void)
9998
{
10099
git_index *index;
@@ -129,3 +128,20 @@ void test_merge_trees_commits__df_conflict(void)
129128

130129
git_index_free(index);
131130
}
131+
132+
void test_merge_trees_commits__fail_on_conflict(void)
133+
{
134+
git_index *index;
135+
git_merge_options opts = GIT_MERGE_OPTIONS_INIT;
136+
137+
opts.tree_flags |= GIT_MERGE_TREE_FAIL_ON_CONFLICT;
138+
139+
cl_git_fail_with(GIT_EMERGECONFLICT,
140+
merge_trees_from_branches(&index, repo, "df_side1", "df_side2", &opts));
141+
142+
cl_git_fail_with(GIT_EMERGECONFLICT,
143+
merge_commits_from_branches(&index, repo, "master", "unrelated", &opts));
144+
cl_git_fail_with(GIT_EMERGECONFLICT,
145+
merge_commits_from_branches(&index, repo, "master", "branch", &opts));
146+
}
147+

0 commit comments

Comments
 (0)