diff options
author | Edward Thomson <ethomson@microsoft.com> | 2013-04-02 07:16:21 +0400 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2013-05-01 00:31:31 +0400 |
commit | bec65a5e994bc4701216c9ca2c7dae83770b3edc (patch) | |
tree | 1e941e76b80245dcfb4853d7c6dc231c7aab7699 /tests-clar/merge | |
parent | 5e2261aca86310aa180eab5ccdc345b1539b024d (diff) |
merge!
Diffstat (limited to 'tests-clar/merge')
-rw-r--r-- | tests-clar/merge/merge_helpers.c | 224 | ||||
-rw-r--r-- | tests-clar/merge/merge_helpers.h | 62 | ||||
-rw-r--r-- | tests-clar/merge/trees/automerge.c | 217 | ||||
-rw-r--r-- | tests-clar/merge/trees/modeconflict.c | 59 | ||||
-rw-r--r-- | tests-clar/merge/trees/treediff.c | 279 | ||||
-rw-r--r-- | tests-clar/merge/trees/trivial.c | 396 | ||||
-rw-r--r-- | tests-clar/merge/workdir/setup.c (renamed from tests-clar/merge/setup.c) | 21 |
7 files changed, 1248 insertions, 10 deletions
diff --git a/tests-clar/merge/merge_helpers.c b/tests-clar/merge/merge_helpers.c new file mode 100644 index 000000000..b10e9ec32 --- /dev/null +++ b/tests-clar/merge/merge_helpers.c @@ -0,0 +1,224 @@ +#include "clar_libgit2.h" +#include "buffer.h" +#include "refs.h" +#include "tree.h" +#include "merge_helpers.h" +#include "merge.h" +#include "git2/merge.h" + +int merge_trees_from_branches( + git_index **index, git_repository *repo, + const char *ours_name, const char *theirs_name, + git_merge_tree_opts *opts) +{ + git_commit *our_commit, *their_commit, *ancestor_commit = NULL; + git_tree *our_tree, *their_tree, *ancestor_tree = NULL; + git_oid our_oid, their_oid, ancestor_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)); + cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); + + git_buf_clear(&branch_buf); + git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs_name); + 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)); + + error = git_merge_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit)); + + if (error != GIT_ENOTFOUND) { + cl_git_pass(error); + + cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)); + cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit)); + } + + 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)); + + git_buf_free(&branch_buf); + git_tree_free(our_tree); + git_tree_free(their_tree); + git_tree_free(ancestor_tree); + git_commit_free(our_commit); + git_commit_free(their_commit); + git_commit_free(ancestor_commit); + + return 0; +} + +static int index_entry_eq_merge_index_entry(const struct merge_index_entry *expected, const git_index_entry *actual) +{ + git_oid expected_oid; + bool test_oid; + + if (strlen(expected->oid_str) != 0) { + cl_git_pass(git_oid_fromstr(&expected_oid, expected->oid_str)); + test_oid = 1; + } else + test_oid = 0; + + if (actual->mode != expected->mode || + (test_oid && git_oid_cmp(&actual->oid, &expected_oid) != 0) || + git_index_entry_stage(actual) != expected->stage) + return 0; + + if (actual->mode == 0 && (actual->path != NULL || strlen(expected->path) > 0)) + return 0; + + if (actual->mode != 0 && (strcmp(actual->path, expected->path) != 0)) + return 0; + + return 1; +} + +static int name_entry_eq(const char *expected, const char *actual) +{ + if (strlen(expected) == 0) + return (actual == NULL) ? 1 : 0; + + return (strcmp(expected, actual) == 0) ? 1 : 0; +} + +static int index_conflict_data_eq_merge_diff(const struct merge_index_conflict_data *expected, git_merge_diff *actual) +{ + if (!index_entry_eq_merge_index_entry((const struct merge_index_entry *)&expected->ancestor, &actual->ancestor_entry) || + !index_entry_eq_merge_index_entry((const struct merge_index_entry *)&expected->ours, &actual->our_entry) || + !index_entry_eq_merge_index_entry((const struct merge_index_entry *)&expected->theirs, &actual->their_entry)) + return 0; + + if (expected->ours.status != actual->our_status || + expected->theirs.status != actual->their_status) + return 0; + + return 1; +} + +int merge_test_merge_conflicts(git_vector *conflicts, const struct merge_index_conflict_data expected[], size_t expected_len) +{ + git_merge_diff *actual; + size_t i; + + if (conflicts->length != expected_len) + return 0; + + for (i = 0; i < expected_len; i++) { + actual = conflicts->contents[i]; + + if (!index_conflict_data_eq_merge_diff(&expected[i], actual)) + return 0; + } + + return 1; +} + +int merge_test_index(git_index *index, const struct merge_index_entry expected[], size_t expected_len) +{ + size_t i; + const git_index_entry *index_entry; + + /* + dump_index_entries(&index->entries); + */ + + if (git_index_entrycount(index) != expected_len) + return 0; + + for (i = 0; i < expected_len; i++) { + if ((index_entry = git_index_get_byindex(index, i)) == NULL) + return 0; + + if (!index_entry_eq_merge_index_entry(&expected[i], index_entry)) + return 0; + } + + return 1; +} + +int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], size_t expected_len) +{ + size_t i; + const git_index_reuc_entry *reuc_entry; + git_oid expected_oid; + + /* + dump_reuc(index); + */ + + if (git_index_reuc_entrycount(index) != expected_len) + return 0; + + for (i = 0; i < expected_len; i++) { + if ((reuc_entry = git_index_reuc_get_byindex(index, i)) == NULL) + return 0; + + if (strcmp(reuc_entry->path, expected[i].path) != 0 || + reuc_entry->mode[0] != expected[i].ancestor_mode || + reuc_entry->mode[1] != expected[i].our_mode || + reuc_entry->mode[2] != expected[i].their_mode) + return 0; + + if (expected[i].ancestor_mode > 0) { + cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].ancestor_oid_str)); + + if (git_oid_cmp(&reuc_entry->oid[0], &expected_oid) != 0) + return 0; + } + + if (expected[i].our_mode > 0) { + cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].our_oid_str)); + + if (git_oid_cmp(&reuc_entry->oid[1], &expected_oid) != 0) + return 0; + } + + if (expected[i].their_mode > 0) { + cl_git_pass(git_oid_fromstr(&expected_oid, expected[i].their_oid_str)); + + if (git_oid_cmp(&reuc_entry->oid[2], &expected_oid) != 0) + return 0; + } + } + + return 1; +} + +int dircount(void *payload, git_buf *pathbuf) +{ + int *entries = payload; + size_t len = git_buf_len(pathbuf); + + if (len < 5 || strcmp(pathbuf->ptr + (git_buf_len(pathbuf) - 5), "/.git") != 0) + (*entries)++; + + return 0; +} + +int merge_test_workdir(git_repository *repo, const struct merge_index_entry expected[], size_t expected_len) +{ + size_t actual_len = 0, i; + git_oid actual_oid, expected_oid; + git_buf wd = GIT_BUF_INIT; + + git_buf_puts(&wd, repo->workdir); + git_path_direach(&wd, dircount, &actual_len); + + if (actual_len != expected_len) + return 0; + + for (i = 0; i < expected_len; i++) { + git_blob_create_fromworkdir(&actual_oid, repo, expected[i].path); + git_oid_fromstr(&expected_oid, expected[i].oid_str); + + if (git_oid_cmp(&actual_oid, &expected_oid) != 0) + return 0; + } + + git_buf_free(&wd); + + return 1; +} diff --git a/tests-clar/merge/merge_helpers.h b/tests-clar/merge/merge_helpers.h new file mode 100644 index 000000000..1a0b8921b --- /dev/null +++ b/tests-clar/merge/merge_helpers.h @@ -0,0 +1,62 @@ +#ifndef INCLUDE_cl_merge_helpers_h__ +#define INCLUDE_cl_merge_helpers_h__ + +#include "merge.h" +#include "git2/merge.h" + +struct merge_index_entry { + uint16_t mode; + char oid_str[41]; + int stage; + char path[128]; +}; + +struct merge_name_entry { + char ancestor_path[128]; + char our_path[128]; + char their_path[128]; +}; + +struct merge_index_with_status { + uint16_t mode; + char oid_str[41]; + int stage; + char path[128]; + unsigned int status; +}; + +struct merge_reuc_entry { + char path[128]; + unsigned int ancestor_mode; + unsigned int our_mode; + unsigned int their_mode; + char ancestor_oid_str[41]; + char our_oid_str[41]; + char their_oid_str[41]; +}; + +struct merge_index_conflict_data { + struct merge_index_with_status ancestor; + struct merge_index_with_status ours; + struct merge_index_with_status theirs; + git_merge_diff_type_t change_type; +}; + +int merge_trees_from_branches( + git_index **index, git_repository *repo, + const char *ours_name, const char *theirs_name, + git_merge_tree_opts *opts); + +int merge_test_diff_list(git_merge_diff_list *diff_list, const struct merge_index_entry expected[], size_t expected_len); + +int merge_test_merge_conflicts(git_vector *conflicts, const struct merge_index_conflict_data expected[], size_t expected_len); + +int merge_test_index(git_index *index, const struct merge_index_entry expected[], size_t expected_len); + +int merge_test_names(git_index *index, const struct merge_name_entry expected[], size_t expected_len); + +int merge_test_reuc(git_index *index, const struct merge_reuc_entry expected[], size_t expected_len); + +int merge_test_workdir(git_repository *repo, const struct merge_index_entry expected[], size_t expected_len); + +#endif diff --git a/tests-clar/merge/trees/automerge.c b/tests-clar/merge/trees/automerge.c new file mode 100644 index 000000000..7592a926e --- /dev/null +++ b/tests-clar/merge/trees/automerge.c @@ -0,0 +1,217 @@ +#include "clar_libgit2.h" +#include "git2/repository.h" +#include "git2/merge.h" +#include "buffer.h" +#include "merge.h" +#include "../merge_helpers.h" +#include "fileops.h" + +static git_repository *repo; + +#define TEST_REPO_PATH "merge-resolve" +#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index" + +#define THEIRS_AUTOMERGE_BRANCH "branch" + +#define THEIRS_UNRELATED_BRANCH "unrelated" +#define THEIRS_UNRELATED_OID "55b4e4687e7a0d9ca367016ed930f385d4022e6f" +#define THEIRS_UNRELATED_PARENT "d6cf6c7741b3316826af1314042550c97ded1d50" + +#define OURS_DIRECTORY_FILE "df_side1" +#define THEIRS_DIRECTORY_FILE "df_side2" + +/* Non-conflicting files, index entries are common to every merge operation */ +#define ADDED_IN_MASTER_INDEX_ENTRY \ + { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" } +#define AUTOMERGEABLE_INDEX_ENTRY \ + { 0100644, "f2e1550a0c9e53d5811175864a29536642ae3821", 0, "automergeable.txt" } +#define CHANGED_IN_BRANCH_INDEX_ENTRY \ + { 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0, "changed-in-branch.txt" } +#define CHANGED_IN_MASTER_INDEX_ENTRY \ + { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" } +#define UNCHANGED_INDEX_ENTRY \ + { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" } + +/* Expected REUC entries */ +#define AUTOMERGEABLE_REUC_ENTRY \ + { "automergeable.txt", 0100644, 0100644, 0100644, \ + "6212c31dab5e482247d7977e4f0dd3601decf13b", \ + "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", \ + "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe" } +#define CONFLICTING_REUC_ENTRY \ + { "conflicting.txt", 0100644, 0100644, 0100644, \ + "d427e0b2e138501a3d15cc376077a3631e15bd46", \ + "4e886e602529caa9ab11d71f86634bd1b6e0de10", \ + "2bd0a343aeef7a2cf0d158478966a6e587ff3863" } +#define REMOVED_IN_BRANCH_REUC_ENTRY \ + { "removed-in-branch.txt", 0100644, 0100644, 0, \ + "dfe3f22baa1f6fce5447901c3086bae368de6bdd", \ + "dfe3f22baa1f6fce5447901c3086bae368de6bdd", \ + "" } +#define REMOVED_IN_MASTER_REUC_ENTRY \ + { "removed-in-master.txt", 0100644, 0, 0100644, \ + "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", \ + "", \ + "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5" } + +#define AUTOMERGEABLE_MERGED_FILE \ + "this file is changed in master\n" \ + "this file is automergeable\n" \ + "this file is automergeable\n" \ + "this file is automergeable\n" \ + "this file is automergeable\n" \ + "this file is automergeable\n" \ + "this file is automergeable\n" \ + "this file is automergeable\n" \ + "this file is changed in branch\n" + +#define AUTOMERGEABLE_MERGED_FILE_CRLF \ + "this file is changed in master\r\n" \ + "this file is automergeable\r\n" \ + "this file is automergeable\r\n" \ + "this file is automergeable\r\n" \ + "this file is automergeable\r\n" \ + "this file is automergeable\r\n" \ + "this file is automergeable\r\n" \ + "this file is automergeable\r\n" \ + "this file is changed in branch\r\n" + +// Fixture setup and teardown +void test_merge_trees_automerge__initialize(void) +{ + repo = cl_git_sandbox_init(TEST_REPO_PATH); +} + +void test_merge_trees_automerge__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_merge_trees_automerge__automerge(void) +{ + git_index *index; + const git_index_entry *entry; + git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT; + git_blob *blob; + + 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(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts)); + + cl_assert(merge_test_index(index, merge_index_entries, 8)); + cl_assert(merge_test_reuc(index, merge_reuc_entries, 3)); + + cl_assert((entry = git_index_get_bypath(index, "automergeable.txt", 0)) != NULL); + cl_assert(entry->file_size == strlen(AUTOMERGEABLE_MERGED_FILE)); + + cl_git_pass(git_object_lookup((git_object **)&blob, repo, &entry->oid, GIT_OBJ_BLOB)); + cl_assert(memcmp(git_blob_rawcontent(blob), AUTOMERGEABLE_MERGED_FILE, entry->file_size) == 0); + + git_index_free(index); + git_blob_free(blob); +} + +void test_merge_trees_automerge__favor_ours(void) +{ + git_index *index; + git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_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, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 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, + }; + + opts.automerge_flags = GIT_MERGE_AUTOMERGE_FAVOR_OURS; + + cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts)); + + cl_assert(merge_test_index(index, merge_index_entries, 6)); + cl_assert(merge_test_reuc(index, merge_reuc_entries, 4)); + + git_index_free(index); +} + +void test_merge_trees_automerge__favor_theirs(void) +{ + git_index *index; + git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_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, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 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, + }; + + opts.automerge_flags = GIT_MERGE_AUTOMERGE_FAVOR_THEIRS; + + cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_AUTOMERGE_BRANCH, &opts)); + + cl_assert(merge_test_index(index, merge_index_entries, 6)); + cl_assert(merge_test_reuc(index, merge_reuc_entries, 4)); + + git_index_free(index); +} + +void test_merge_trees_automerge__unrelated(void) +{ + git_index *index; + git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT; + + struct merge_index_entry merge_index_entries[] = { + { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt" }, + { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 2, "automergeable.txt" }, + { 0100644, "d07ec190c306ec690bac349e87d01c4358e49bb2", 3, "automergeable.txt" }, + { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt" }, + { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt" }, + { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 2, "conflicting.txt" }, + { 0100644, "4b253da36a0ae8bfce63aeabd8c5b58429925594", 3, "conflicting.txt" }, + { 0100644, "ef58fdd8086c243bdc81f99e379acacfd21d32d6", 0, "new-in-unrelated1.txt" }, + { 0100644, "948ba6e701c1edab0c2d394fb7c5538334129793", 0, "new-in-unrelated2.txt" }, + { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt" }, + { 0100644, "c8f06f2e3bb2964174677e91f0abead0e43c9e5d", 0, "unchanged.txt" }, + }; + + cl_git_pass(merge_trees_from_branches(&index, repo, "master", THEIRS_UNRELATED_BRANCH, &opts)); + + cl_assert(merge_test_index(index, merge_index_entries, 11)); + + git_index_free(index); +} diff --git a/tests-clar/merge/trees/modeconflict.c b/tests-clar/merge/trees/modeconflict.c new file mode 100644 index 000000000..0661ce5b3 --- /dev/null +++ b/tests-clar/merge/trees/modeconflict.c @@ -0,0 +1,59 @@ +#include "clar_libgit2.h" +#include "git2/repository.h" +#include "git2/merge.h" +#include "buffer.h" +#include "merge.h" +#include "../merge_helpers.h" +#include "fileops.h" + +static git_repository *repo; + +#define TEST_REPO_PATH "merge-resolve" + +#define DF_SIDE1_BRANCH "df_side1" +#define DF_SIDE2_BRANCH "df_side2" + +// Fixture setup and teardown +void test_merge_trees_modeconflict__initialize(void) +{ + repo = cl_git_sandbox_init(TEST_REPO_PATH); +} + +void test_merge_trees_modeconflict__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +void test_merge_trees_modeconflict__df_conflict(void) +{ + git_index *index; + + struct merge_index_entry merge_index_entries[] = { + { 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 2, "dir-10" }, + { 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 3, "dir-10" }, + { 0100644, "43aafd43bea779ec74317dc361f45ae3f532a505", 0, "dir-6" }, + { 0100644, "a031a28ae70e33a641ce4b8a8f6317f1ab79dee4", 3, "dir-7" }, + { 0100644, "5012fd565b1393bdfda1805d4ec38ce6619e1fd1", 1, "dir-7/file.txt" }, + { 0100644, "a5563304ddf6caba25cb50323a2ea6f7dbfcadca", 2, "dir-7/file.txt" }, + { 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8" }, + { 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 2, "dir-9" }, + { 0100644, "fc4c636d6515e9e261f9260dbcf3cc6eca97ea08", 1, "dir-9/file.txt" }, + { 0100644, "76ab0e2868197ec158ddd6c78d8a0d2fd73d38f9", 3, "dir-9/file.txt" }, + { 0100644, "5c2411f8075f48a6b2fdb85ebc0d371747c4df15", 0, "file-1/new" }, + { 0100644, "a39a620dae5bc8b4e771cd4d251b7d080401a21e", 1, "file-2" }, + { 0100644, "d963979c237d08b6ba39062ee7bf64c7d34a27f8", 2, "file-2" }, + { 0100644, "5c341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d", 0, "file-2/new" }, + { 0100644, "9efe7723802d4305142eee177e018fee1572c4f4", 0, "file-3/new" }, + { 0100644, "bacac9b3493509aa15e1730e1545fc0919d1dae0", 1, "file-4" }, + { 0100644, "7663fce0130db092936b137cabd693ec234eb060", 3, "file-4" }, + { 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new" }, + { 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 2, "file-5/new" }, + { 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 3, "file-5/new" }, + }; + + cl_git_pass(merge_trees_from_branches(&index, repo, DF_SIDE1_BRANCH, DF_SIDE2_BRANCH, NULL)); + + cl_assert(merge_test_index(index, merge_index_entries, 20)); + + git_index_free(index); +} diff --git a/tests-clar/merge/trees/treediff.c b/tests-clar/merge/trees/treediff.c new file mode 100644 index 000000000..b2554f8be --- /dev/null +++ b/tests-clar/merge/trees/treediff.c @@ -0,0 +1,279 @@ +#include "clar_libgit2.h" +#include "git2/tree.h" +#include "merge.h" +#include "../merge_helpers.h" +#include "diff.h" +#include "hashsig.h" + +static git_repository *repo; + +#define TEST_REPO_PATH "merge-resolve" + +#define TREE_OID_ANCESTOR "0d52e3a556e189ba0948ae56780918011c1b167d" +#define TREE_OID_MASTER "1f81433e3161efbf250576c58fede7f6b836f3d3" +#define TREE_OID_BRANCH "eea9286df54245fea72c5b557291470eb825f38f" + +#define TREE_OID_DF_ANCESTOR "b8a3a806d3950e8c0a03a34f234a92eff0e2c68d" +#define TREE_OID_DF_SIDE1 "ee1d6f164893c1866a323f072eeed36b855656be" +#define TREE_OID_DF_SIDE2 "6178885b38fe96e825ac0f492c0a941f288b37f6" + +void test_merge_trees_treediff__initialize(void) +{ + repo = cl_git_sandbox_init(TEST_REPO_PATH); +} + +void test_merge_trees_treediff__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + +struct treediff_cb_data { + struct merge_index_conflict_data *conflict_data; + size_t conflict_data_len; + + size_t idx; +}; + +static void test_find_differences( + const char *ancestor_oidstr, + const char *ours_oidstr, + const char *theirs_oidstr, + struct merge_index_conflict_data *treediff_conflict_data, + size_t treediff_conflict_data_len) +{ + 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; + struct treediff_cb_data treediff_cb_data = {0}; + + cl_git_pass(git_oid_fromstr(&ancestor_oid, ancestor_oidstr)); + cl_git_pass(git_oid_fromstr(&ours_oid, ours_oidstr)); + cl_git_pass(git_oid_fromstr(&theirs_oid, theirs_oidstr)); + + cl_git_pass(git_tree_lookup(&ancestor_tree, repo, &ancestor_oid)); + 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)); + + /* + dump_merge_index(merge_index); + */ + + cl_assert(treediff_conflict_data_len == merge_diff_list->conflicts.length); + + treediff_cb_data.conflict_data = treediff_conflict_data; + treediff_cb_data.conflict_data_len = treediff_conflict_data_len; + + cl_assert(merge_test_merge_conflicts(&merge_diff_list->conflicts, treediff_conflict_data, treediff_conflict_data_len)); + + git_tree_free(ancestor_tree); + git_tree_free(ours_tree); + git_tree_free(theirs_tree); + + git_merge_diff_list__free(merge_diff_list); +} + +void test_merge_trees_treediff__simple(void) +{ + struct merge_index_conflict_data treediff_conflict_data[] = { + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "233c0919c998ed110a4b6ff36f353aec8b713487", 0, "added-in-master.txt", GIT_DELTA_ADDED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE + }, + + { + { 0100644, "6212c31dab5e482247d7977e4f0dd3601decf13b", 0, "automergeable.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "ee3fa1b8c00aff7fe02065fdb50864bb0d932ccf", 0, "automergeable.txt", GIT_DELTA_MODIFIED }, + { 0100644, "058541fc37114bfc1dddf6bd6bffc7fae5c2e6fe", 0, "automergeable.txt", GIT_DELTA_MODIFIED }, + GIT_MERGE_DIFF_BOTH_MODIFIED + }, + + { + { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-branch.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "4eb04c9e79e88f6640d01ff5b25ca2a60764f216", 0, "changed-in-branch.txt", GIT_DELTA_MODIFIED }, + GIT_MERGE_DIFF_NONE + }, + + { + { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "11deab00b2d3a6f5a3073988ac050c2d7b6655e2", 0, "changed-in-master.txt", GIT_DELTA_MODIFIED }, + { 0100644, "ab6c44a2e84492ad4b41bb6bac87353e9d02ac8b", 0, "changed-in-master.txt", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE + }, + + { + { 0100644, "d427e0b2e138501a3d15cc376077a3631e15bd46", 0, "conflicting.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "4e886e602529caa9ab11d71f86634bd1b6e0de10", 0, "conflicting.txt", GIT_DELTA_MODIFIED }, + { 0100644, "2bd0a343aeef7a2cf0d158478966a6e587ff3863", 0, "conflicting.txt", GIT_DELTA_MODIFIED }, + GIT_MERGE_DIFF_BOTH_MODIFIED + }, + + { + { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "dfe3f22baa1f6fce5447901c3086bae368de6bdd", 0, "removed-in-branch.txt", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_NONE + }, + + { + { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0100644, "5c3b68a71fc4fa5d362fd3875e53137c6a5ab7a5", 0, "removed-in-master.txt", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE + }, + }; + + test_find_differences(TREE_OID_ANCESTOR, TREE_OID_MASTER, TREE_OID_BRANCH, treediff_conflict_data, 7); +} + +void test_merge_trees_treediff__df_conflicts(void) +{ + struct merge_index_conflict_data treediff_conflict_data[] = { + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "49130a28ef567af9a6a6104c38773fedfa5f9742", 0, "dir-10", GIT_DELTA_ADDED }, + { 0100644, "6c06dcd163587c2cc18be44857e0b71116382aeb", 0, "dir-10", GIT_DELTA_ADDED }, + GIT_MERGE_DIFF_BOTH_ADDED, + }, + + { + { 0100644, "242591eb280ee9eeb2ce63524b9a8b9bc4cb515d", 0, "dir-10/file.txt", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_BOTH_DELETED, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "43aafd43bea779ec74317dc361f45ae3f532a505", 0, "dir-6", GIT_DELTA_ADDED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0100644, "cf8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d", 0, "dir-6/file.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "cf8c5cc8a85a1ff5a4ba51e0bc7cf5665669924d", 0, "dir-6/file.txt", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "a031a28ae70e33a641ce4b8a8f6317f1ab79dee4", 0, "dir-7", GIT_DELTA_ADDED }, + GIT_MERGE_DIFF_DIRECTORY_FILE, + }, + + { + { 0100644, "5012fd565b1393bdfda1805d4ec38ce6619e1fd1", 0, "dir-7/file.txt", GIT_DELTA_UNMODIFIED }, + { 0100644, "a5563304ddf6caba25cb50323a2ea6f7dbfcadca", 0, "dir-7/file.txt", GIT_DELTA_MODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_DF_CHILD, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "e9ad6ec3e38364a3d07feda7c4197d4d845c53b5", 0, "dir-8", GIT_DELTA_ADDED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0100644, "f20c9063fa0bda9a397c96947a7b687305c49753", 0, "dir-8/file.txt", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0100644, "f20c9063fa0bda9a397c96947a7b687305c49753", 0, "dir-8/file.txt", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "3ef4d30382ca33fdeba9fda895a99e0891ba37aa", 0, "dir-9", GIT_DELTA_ADDED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_DIRECTORY_FILE, + }, + + { + { 0100644, "fc4c636d6515e9e261f9260dbcf3cc6eca97ea08", 0, "dir-9/file.txt", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0100644, "76ab0e2868197ec158ddd6c78d8a0d2fd73d38f9", 0, "dir-9/file.txt", GIT_DELTA_MODIFIED }, + GIT_MERGE_DIFF_DF_CHILD, + }, + + { + { 0100644, "1e4ff029aee68d0d69ef9eb6efa6cbf1ec732f99", 0, "file-1", GIT_DELTA_UNMODIFIED }, + { 0100644, "1e4ff029aee68d0d69ef9eb6efa6cbf1ec732f99", 0, "file-1", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "5c2411f8075f48a6b2fdb85ebc0d371747c4df15", 0, "file-1/new", GIT_DELTA_ADDED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0100644, "a39a620dae5bc8b4e771cd4d251b7d080401a21e", 0, "file-2", GIT_DELTA_UNMODIFIED }, + { 0100644, "d963979c237d08b6ba39062ee7bf64c7d34a27f8", 0, "file-2", GIT_DELTA_MODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_DIRECTORY_FILE, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "5c341ead2ba6f2af98ce5ec3fe84f6b6d2899c0d", 0, "file-2/new", GIT_DELTA_ADDED }, + GIT_MERGE_DIFF_DF_CHILD, + }, + + { + { 0100644, "032ebc5ab85d9553bb187d3cd40875ff23a63ed0", 0, "file-3", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0100644, "032ebc5ab85d9553bb187d3cd40875ff23a63ed0", 0, "file-3", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "9efe7723802d4305142eee177e018fee1572c4f4", 0, "file-3/new", GIT_DELTA_ADDED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_NONE, + }, + + { + { 0100644, "bacac9b3493509aa15e1730e1545fc0919d1dae0", 0, "file-4", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0100644, "7663fce0130db092936b137cabd693ec234eb060", 0, "file-4", GIT_DELTA_MODIFIED }, + GIT_MERGE_DIFF_DIRECTORY_FILE, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "e49f917b448d1340b31d76e54ba388268fd4c922", 0, "file-4/new", GIT_DELTA_ADDED }, + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + GIT_MERGE_DIFF_DF_CHILD, + }, + + { + { 0100644, "ac4045f965119e6998f4340ed0f411decfb3ec05", 0, "file-5", GIT_DELTA_UNMODIFIED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + { 0, "", 0, "", GIT_DELTA_DELETED }, + GIT_MERGE_DIFF_BOTH_DELETED, + }, + + { + { 0, "", 0, "", GIT_DELTA_UNMODIFIED }, + { 0100644, "cab2cf23998b40f1af2d9d9a756dc9e285a8df4b", 0, "file-5/new", GIT_DELTA_ADDED }, + { 0100644, "f5504f36e6f4eb797a56fc5bac6c6c7f32969bf2", 0, "file-5/new", GIT_DELTA_ADDED }, + GIT_MERGE_DIFF_BOTH_ADDED, + }, + }; + + test_find_differences(TREE_OID_DF_ANCESTOR, TREE_OID_DF_SIDE1, TREE_OID_DF_SIDE2, treediff_conflict_data, 20); +} + diff --git a/tests-clar/merge/trees/trivial.c b/tests-clar/merge/trees/trivial.c new file mode 100644 index 000000000..54b07e74a --- /dev/null +++ b/tests-clar/merge/trees/trivial.c @@ -0,0 +1,396 @@ +#include "clar_libgit2.h" +#include "git2/repository.h" +#include "git2/merge.h" +#include "merge.h" +#include "../merge_helpers.h" +#include "refs.h" +#include "fileops.h" + +static git_repository *repo; + +#define TEST_REPO_PATH "merge-resolve" +#define TEST_INDEX_PATH TEST_REPO_PATH "/.git/index" + + +// Fixture setup and teardown +void test_merge_trees_trivial__initialize(void) +{ + repo = cl_git_sandbox_init(TEST_REPO_PATH); +} + +void test_merge_trees_trivial__cleanup(void) +{ + cl_git_sandbox_cleanup(); +} + + +static int merge_trivial(git_index **index, const char *ours, const char *theirs, bool automerge) +{ + git_commit *our_commit, *their_commit, *ancestor_commit; + git_tree *our_tree, *their_tree, *ancestor_tree; + git_oid our_oid, their_oid, ancestor_oid; + git_buf branch_buf = GIT_BUF_INIT; + git_merge_tree_opts opts = GIT_MERGE_TREE_OPTS_INIT; + + opts.automerge_flags |= automerge ? 0 : GIT_MERGE_AUTOMERGE_NONE; + + git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, ours); + cl_git_pass(git_reference_name_to_id(&our_oid, repo, branch_buf.ptr)); + cl_git_pass(git_commit_lookup(&our_commit, repo, &our_oid)); + + git_buf_clear(&branch_buf); + git_buf_printf(&branch_buf, "%s%s", GIT_REFS_HEADS_DIR, theirs); + 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_base(&ancestor_oid, repo, git_commit_id(our_commit), git_commit_id(their_commit))); + cl_git_pass(git_commit_lookup(&ancestor_commit, repo, &ancestor_oid)); + + cl_git_pass(git_commit_tree(&ancestor_tree, ancestor_commit)); + 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)); + + git_buf_free(&branch_buf); + git_tree_free(our_tree); + git_tree_free(their_tree); + git_tree_free(ancestor_tree); + git_commit_free(our_commit); + git_commit_free(their_commit); + git_commit_free(ancestor_commit); + + return 0; +} + +static int merge_trivial_conflict_entrycount(git_index *index) +{ + const git_index_entry *entry; + size_t count = 0; + size_t i; + + for (i = 0; i < git_index_entrycount(index); i++) { + cl_assert(entry = git_index_get_byindex(index, i)); + + if (git_index_entry_stage(entry) > 0) + count++; + } + + return count; +} + +/* 2ALT: ancest:(empty)+, head:*empty*, remote:remote = result:remote */ +void test_merge_trees_trivial__2alt(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-2alt", "trivial-2alt-branch", 0)); + + cl_assert(entry = git_index_get_bypath(result, "new-in-branch.txt", 0)); + cl_assert(git_index_reuc_entrycount(result) == 0); + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 3ALT: ancest:(empty)+, head:head, remote:*empty* = result:head */ +void test_merge_trees_trivial__3alt(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-3alt", "trivial-3alt-branch", 0)); + + cl_assert(entry = git_index_get_bypath(result, "new-in-3alt.txt", 0)); + cl_assert(git_index_reuc_entrycount(result) == 0); + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 4: ancest:(empty)^, head:head, remote:remote = result:no merge */ +void test_merge_trees_trivial__4(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-4", "trivial-4-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "new-and-different.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "new-and-different.txt", 2)); + cl_assert(entry = git_index_get_bypath(result, "new-and-different.txt", 3)); + + git_index_free(result); +} + +/* 5ALT: ancest:*, head:head, remote:head = result:head */ +void test_merge_trees_trivial__5alt_1(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-5alt-1", "trivial-5alt-1-branch", 0)); + + cl_assert(entry = git_index_get_bypath(result, "new-and-same.txt", 0)); + cl_assert(git_index_reuc_entrycount(result) == 0); + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 5ALT: ancest:*, head:head, remote:head = result:head */ +void test_merge_trees_trivial__5alt_2(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-5alt-2", "trivial-5alt-2-branch", 0)); + + cl_assert(entry = git_index_get_bypath(result, "modified-to-same.txt", 0)); + cl_assert(git_index_reuc_entrycount(result) == 0); + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */ +void test_merge_trees_trivial__6(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-6", "trivial-6-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-both.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 1); + cl_assert(entry = git_index_get_bypath(result, "removed-in-both.txt", 1)); + + git_index_free(result); +} + +/* 6: ancest:ancest+, head:(empty), remote:(empty) = result:no merge */ +void test_merge_trees_trivial__6_automerge(void) +{ + git_index *result; + const git_index_entry *entry; + const git_index_reuc_entry *reuc; + + cl_git_pass(merge_trivial(&result, "trivial-6", "trivial-6-branch", 1)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-both.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 1); + cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-both.txt")); + + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */ +void test_merge_trees_trivial__8(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-8", "trivial-8-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-8.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "removed-in-8.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "removed-in-8.txt", 3)); + + git_index_free(result); +} + +/* 8: ancest:ancest^, head:(empty), remote:ancest = result:no merge */ +void test_merge_trees_trivial__8_automerge(void) +{ + git_index *result; + const git_index_entry *entry; + const git_index_reuc_entry *reuc; + + cl_git_pass(merge_trivial(&result, "trivial-8", "trivial-8-branch", 1)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-8.txt", 0)) == NULL); + + cl_assert(git_index_reuc_entrycount(result) == 1); + cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-8.txt")); + + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 7: ancest:ancest+, head:(empty), remote:remote = result:no merge */ +void test_merge_trees_trivial__7(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-7", "trivial-7-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-7.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 3)); + + git_index_free(result); +} + +/* 7: ancest:ancest+, head:(empty), remote:remote = result:no merge */ +void test_merge_trees_trivial__7_automerge(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-7", "trivial-7-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-7.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "removed-in-7.txt", 3)); + + git_index_free(result); +} + +/* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */ +void test_merge_trees_trivial__10(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-10", "trivial-10-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 2)); + + git_index_free(result); +} + +/* 10: ancest:ancest^, head:ancest, remote:(empty) = result:no merge */ +void test_merge_trees_trivial__10_automerge(void) +{ + git_index *result; + const git_index_entry *entry; + const git_index_reuc_entry *reuc; + + cl_git_pass(merge_trivial(&result, "trivial-10", "trivial-10-branch", 1)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-10-branch.txt", 0)) == NULL); + + cl_assert(git_index_reuc_entrycount(result) == 1); + cl_assert(reuc = git_index_reuc_get_bypath(result, "removed-in-10-branch.txt")); + + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 9: ancest:ancest+, head:head, remote:(empty) = result:no merge */ +void test_merge_trees_trivial__9(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-9", "trivial-9-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 2)); + + git_index_free(result); +} + +/* 9: ancest:ancest+, head:head, remote:(empty) = result:no merge */ +void test_merge_trees_trivial__9_automerge(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-9", "trivial-9-branch", 1)); + + cl_assert((entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 2); + cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "removed-in-9-branch.txt", 2)); + + git_index_free(result); +} + +/* 13: ancest:ancest+, head:head, remote:ancest = result:head */ +void test_merge_trees_trivial__13(void) +{ + git_index *result; + const git_index_entry *entry; + git_oid expected_oid; + + cl_git_pass(merge_trivial(&result, "trivial-13", "trivial-13-branch", 0)); + + cl_assert(entry = git_index_get_bypath(result, "modified-in-13.txt", 0)); + cl_git_pass(git_oid_fromstr(&expected_oid, "1cff9ec6a47a537380dedfdd17c9e76d74259a2b")); + cl_assert(git_oid_cmp(&entry->oid, &expected_oid) == 0); + + cl_assert(git_index_reuc_entrycount(result) == 0); + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 14: ancest:ancest+, head:ancest, remote:remote = result:remote */ +void test_merge_trees_trivial__14(void) +{ + git_index *result; + const git_index_entry *entry; + git_oid expected_oid; + + cl_git_pass(merge_trivial(&result, "trivial-14", "trivial-14-branch", 0)); + + cl_assert(entry = git_index_get_bypath(result, "modified-in-14-branch.txt", 0)); + cl_git_pass(git_oid_fromstr(&expected_oid, "26153a3ff3649b6c2bb652d3f06878c6e0a172f9")); + cl_assert(git_oid_cmp(&entry->oid, &expected_oid) == 0); + + cl_assert(git_index_reuc_entrycount(result) == 0); + cl_assert(merge_trivial_conflict_entrycount(result) == 0); + + git_index_free(result); +} + +/* 11: ancest:ancest+, head:head, remote:remote = result:no merge */ +void test_merge_trees_trivial__11(void) +{ + git_index *result; + const git_index_entry *entry; + + cl_git_pass(merge_trivial(&result, "trivial-11", "trivial-11-branch", 0)); + + cl_assert((entry = git_index_get_bypath(result, "modified-in-both.txt", 0)) == NULL); + cl_assert(git_index_reuc_entrycount(result) == 0); + + cl_assert(merge_trivial_conflict_entrycount(result) == 3); + cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 1)); + cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 2)); + cl_assert(entry = git_index_get_bypath(result, "modified-in-both.txt", 3)); + + git_index_free(result); +} diff --git a/tests-clar/merge/setup.c b/tests-clar/merge/workdir/setup.c index 946c67e7b..6ae9dbb14 100644 --- a/tests-clar/merge/setup.c +++ b/tests-clar/merge/workdir/setup.c @@ -32,15 +32,15 @@ static git_index *repo_index; #define OCTO5_OID "e4f618a2c3ed0669308735727df5ebf2447f022f" // Fixture setup and teardown -void test_merge_setup__initialize(void) +void test_merge_workdir_setup__initialize(void) { repo = cl_git_sandbox_init(TEST_REPO_PATH); - git_repository_index(&repo_index, repo); + git_repository_index(&repo_index, repo); } -void test_merge_setup__cleanup(void) +void test_merge_workdir_setup__cleanup(void) { - git_index_free(repo_index); + git_index_free(repo_index); cl_git_sandbox_cleanup(); } @@ -48,7 +48,8 @@ static void write_file_contents(const char *filename, const char *output) { git_buf file_path_buf = GIT_BUF_INIT; - git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), filename); + git_buf_printf(&file_path_buf, "%s/%s", git_repository_path(repo), + filename); cl_git_rewritefile(file_path_buf.ptr, output); git_buf_free(&file_path_buf); @@ -72,7 +73,7 @@ static int merge_head_foreach_cb(const git_oid *oid, void *payload) return 0; } -void test_merge_setup__head_notfound(void) +void test_merge_workdir_setup__head_notfound(void) { int error; @@ -81,7 +82,7 @@ void test_merge_setup__head_notfound(void) cl_assert(error == GIT_ENOTFOUND); } -void test_merge_setup__head_invalid_oid(void) +void test_merge_workdir_setup__head_invalid_oid(void) { int error; @@ -92,7 +93,7 @@ void test_merge_setup__head_invalid_oid(void) cl_assert(error == -1); } -void test_merge_setup__head_foreach_nonewline(void) +void test_merge_workdir_setup__head_foreach_nonewline(void) { int error; @@ -103,7 +104,7 @@ void test_merge_setup__head_foreach_nonewline(void) cl_assert(error == -1); } -void test_merge_setup__head_foreach_one(void) +void test_merge_workdir_setup__head_foreach_one(void) { const char *expected = THEIRS_SIMPLE_OID; @@ -117,7 +118,7 @@ void test_merge_setup__head_foreach_one(void) cl_assert(cb_data.i == cb_data.len); } -void test_merge_setup__head_foreach_octopus(void) +void test_merge_workdir_setup__head_foreach_octopus(void) { const char *expected[] = { THEIRS_SIMPLE_OID, OCTO1_OID, OCTO2_OID, OCTO3_OID, OCTO4_OID, OCTO5_OID }; |