Load merge.conflictstyle setting from config
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
diff --git a/src/checkout.c b/src/checkout.c
index fcc0f87..960bc61 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -1938,6 +1938,29 @@ static int checkout_data_init(
goto cleanup;
}
+ if ((data->opts.checkout_strategy &
+ (GIT_CHECKOUT_CONFLICT_STYLE_MERGE | GIT_CHECKOUT_CONFLICT_STYLE_DIFF3)) == 0) {
+ const char *conflict_style;
+ git_config *cfg = NULL;
+
+ if ((error = git_repository_config__weakptr(&cfg, repo)) < 0 ||
+ (error = git_config_get_string(&conflict_style, cfg, "merge.conflictstyle")) < 0 ||
+ error == GIT_ENOTFOUND)
+ ;
+ else if (error)
+ goto cleanup;
+ else if (strcmp(conflict_style, "merge") == 0)
+ data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_MERGE;
+ else if (strcmp(conflict_style, "diff3") == 0)
+ data->opts.checkout_strategy |= GIT_CHECKOUT_CONFLICT_STYLE_DIFF3;
+ else {
+ giterr_set(GITERR_CHECKOUT, "unknown style '%s' given for 'merge.conflictstyle'",
+ conflict_style);
+ error = -1;
+ goto cleanup;
+ }
+ }
+
if ((error = git_vector_init(&data->removes, 0, git__strcmp_cb)) < 0 ||
(error = git_vector_init(&data->conflicts, 0, NULL)) < 0 ||
(error = git_pool_init(&data->pool, 1, 0)) < 0 ||
diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c
index 40a07d5..757e20c 100644
--- a/tests/merge/workdir/simple.c
+++ b/tests/merge/workdir/simple.c
@@ -329,6 +329,92 @@ void test_merge_workdir_simple__diff3(void)
git_merge_result_free(result);
}
+void test_merge_workdir_simple__diff3_from_config(void)
+{
+ git_merge_result *result;
+ git_config *config;
+ git_buf conflicting_buf = GIT_BUF_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ ADDED_IN_MASTER_INDEX_ENTRY,
+ AUTOMERGEABLE_INDEX_ENTRY,
+ CHANGED_IN_BRANCH_INDEX_ENTRY,
+ CHANGED_IN_MASTER_INDEX_ENTRY,
+
+ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+ { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+ { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+ UNCHANGED_INDEX_ENTRY,
+ };
+
+ struct merge_reuc_entry merge_reuc_entries[] = {
+ AUTOMERGEABLE_REUC_ENTRY,
+ REMOVED_IN_BRANCH_REUC_ENTRY,
+ REMOVED_IN_MASTER_REUC_ENTRY
+ };
+
+ cl_git_pass(git_repository_config(&config, repo));
+ cl_git_pass(git_config_set_string(config, "merge.conflictstyle", "diff3"));
+
+ cl_assert(result = merge_simple_branch(0, 0));
+ cl_assert(!git_merge_result_is_fastforward(result));
+
+ cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+ TEST_REPO_PATH "/conflicting.txt"));
+ cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_DIFF3_FILE) == 0);
+ git_buf_free(&conflicting_buf);
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+ cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+ git_merge_result_free(result);
+ git_config_free(config);
+}
+
+void test_merge_workdir_simple__merge_overrides_config(void)
+{
+ git_merge_result *result;
+ git_config *config;
+ git_buf conflicting_buf = GIT_BUF_INIT;
+
+ struct merge_index_entry merge_index_entries[] = {
+ ADDED_IN_MASTER_INDEX_ENTRY,
+ AUTOMERGEABLE_INDEX_ENTRY,
+ CHANGED_IN_BRANCH_INDEX_ENTRY,
+ CHANGED_IN_MASTER_INDEX_ENTRY,
+
+ { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 1, "conflicting.txt" },
+ { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" },
+ { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 3, "conflicting.txt" },
+
+ UNCHANGED_INDEX_ENTRY,
+ };
+
+ struct merge_reuc_entry merge_reuc_entries[] = {
+ AUTOMERGEABLE_REUC_ENTRY,
+ REMOVED_IN_BRANCH_REUC_ENTRY,
+ REMOVED_IN_MASTER_REUC_ENTRY
+ };
+
+ cl_git_pass(git_repository_config(&config, repo));
+ cl_git_pass(git_config_set_string(config, "merge.conflictstyle", "diff3"));
+
+ cl_assert(result = merge_simple_branch(0, GIT_CHECKOUT_CONFLICT_STYLE_MERGE));
+ cl_assert(!git_merge_result_is_fastforward(result));
+
+ cl_git_pass(git_futils_readbuffer(&conflicting_buf,
+ TEST_REPO_PATH "/conflicting.txt"));
+ cl_assert(strcmp(conflicting_buf.ptr, CONFLICTING_MERGE_FILE) == 0);
+ git_buf_free(&conflicting_buf);
+
+ cl_assert(merge_test_index(repo_index, merge_index_entries, 8));
+ cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 3));
+
+ git_merge_result_free(result);
+ git_config_free(config);
+}
+
void test_merge_workdir_simple__checkout_ours(void)
{
git_merge_result *result;