From db3462ce7714e2a6ce23130a7046a77860739e05 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Sun, 19 Jan 2014 22:36:50 -0800 Subject: [PATCH] Support union merges --- include/git2/merge.h | 3 +++ src/merge_file.c | 2 ++ tests/merge/workdir/simple.c | 43 ++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/include/git2/merge.h b/include/git2/merge.h index c079ef9c2..ad9b5e2ea 100644 --- a/include/git2/merge.h +++ b/include/git2/merge.h @@ -43,6 +43,9 @@ typedef enum { /* Produce a file containing the "theirs" side of conflicting regions. */ GIT_MERGE_FILE_FAVOR_THEIRS = 2, + + /* Produce a file blending the sides in a union of conflicting regions */ + GIT_MERGE_FILE_FAVOR_UNION = 3, } git_merge_file_favor_t; diff --git a/src/merge_file.c b/src/merge_file.c index fb0e29960..9961ef297 100644 --- a/src/merge_file.c +++ b/src/merge_file.c @@ -156,6 +156,8 @@ int git_merge_files( xmparam.favor = XDL_MERGE_FAVOR_OURS; else if (opts && opts->favor == GIT_MERGE_FILE_FAVOR_THEIRS) xmparam.favor = XDL_MERGE_FAVOR_THEIRS; + else if (opts && opts->favor == GIT_MERGE_FILE_FAVOR_UNION) + xmparam.favor = XDL_MERGE_FAVOR_UNION; xmparam.level = (opts && (opts->flags & GIT_MERGE_FILE_SIMPLIFY_ALNUM)) ? diff --git a/tests/merge/workdir/simple.c b/tests/merge/workdir/simple.c index 757e20c6c..6b152cc4d 100644 --- a/tests/merge/workdir/simple.c +++ b/tests/merge/workdir/simple.c @@ -109,6 +109,10 @@ static git_index *repo_index; "this file is changed in branch and master\n" \ ">>>>>>> 7cb63eed597130ba4abb87b3e544b85021905520\n" +#define CONFLICTING_UNION_FILE \ + "this file is changed in master and branch\n" \ + "this file is changed in branch and master\n" + // Fixture setup and teardown void test_merge_workdir_simple__initialize(void) { @@ -329,6 +333,45 @@ void test_merge_workdir_simple__diff3(void) git_merge_result_free(result); } +void test_merge_workdir_simple__union(void) +{ + git_merge_result *result; + 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, "72cdb057b340205164478565e91eb71647e66891", 0, "conflicting.txt" }, + + UNCHANGED_INDEX_ENTRY, + }; + + struct merge_reuc_entry merge_reuc_entries[] = { + AUTOMERGEABLE_REUC_ENTRY, + CONFLICTING_REUC_ENTRY, + REMOVED_IN_BRANCH_REUC_ENTRY, + REMOVED_IN_MASTER_REUC_ENTRY + }; + + set_core_autocrlf_to(repo, false); + + cl_assert(result = merge_simple_branch(GIT_MERGE_FILE_FAVOR_UNION, 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_UNION_FILE) == 0); + git_buf_free(&conflicting_buf); + + cl_assert(merge_test_index(repo_index, merge_index_entries, 6)); + cl_assert(merge_test_reuc(repo_index, merge_reuc_entries, 4)); + + git_merge_result_free(result); +} + void test_merge_workdir_simple__diff3_from_config(void) { git_merge_result *result;