void test_status_worktree__conflicted_item(void) { git_repository *repo = cl_git_sandbox_init("status"); git_index *index; unsigned int status; git_index_entry ancestor_entry, our_entry, their_entry; memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); ancestor_entry.path = "modified_file"; git_oid_fromstr(&ancestor_entry.oid, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); our_entry.path = "modified_file"; git_oid_fromstr(&our_entry.oid, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); their_entry.path = "modified_file"; git_oid_fromstr(&their_entry.oid, "452e4244b5d083ddf0460acf1ecc74db9dcfa11a"); cl_git_pass(git_status_file(&status, repo, "modified_file")); cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry)); cl_git_pass(git_status_file(&status, repo, "modified_file")); cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status); git_index_free(index); }
void test_diff_index__not_in_head_conflicted(void) { const char *a_commit = "26a125ee1bf"; /* the current HEAD */ git_index_entry theirs = {{0}}; git_index *index; git_diff *diff; const git_diff_delta *delta; git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); cl_git_pass(git_repository_index(&index, g_repo)); cl_git_pass(git_index_read_tree(index, a)); theirs.path = "file_not_in_head"; theirs.mode = GIT_FILEMODE_BLOB; git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); cl_git_pass(git_index_conflict_add(index, NULL, NULL, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, NULL)); cl_assert_equal_i(git_diff_num_deltas(diff), 1); delta = git_diff_get_delta(diff, 0); cl_assert_equal_i(delta->status, GIT_DELTA_CONFLICTED); git_diff_free(diff); git_index_free(index); git_tree_free(a); }
/* * call-seq: * index.conflict_add(conflict) -> nil * * Add or update index entries that represent a conflict. * * +conflict+ has to be a hash containing +:ancestor+, +:ours+ and * +:theirs+ key/value pairs. Any of those paris can be +nil+ (or left out) * to indicate that the file was not present in the respective tree during * the merge. */ static VALUE rb_git_conflict_add(VALUE self, VALUE rb_conflict) { VALUE rb_ancestor, rb_ours, rb_theirs; git_index *index; git_index_entry ancestor, ours, theirs; int error; Check_Type(rb_conflict, T_HASH); rb_ancestor = rb_hash_aref(rb_conflict, CSTR2SYM("ancestor")); rb_ours = rb_hash_aref(rb_conflict, CSTR2SYM("ours")); rb_theirs = rb_hash_aref(rb_conflict, CSTR2SYM("theirs")); if (!NIL_P(rb_ancestor)) rb_git_indexentry_toC(&ancestor, rb_ancestor); if (!NIL_P(rb_ours)) rb_git_indexentry_toC(&ours, rb_ours); if (!NIL_P(rb_theirs)) rb_git_indexentry_toC(&theirs, rb_theirs); Data_Get_Struct(self, git_index, index); error = git_index_conflict_add(index, NIL_P(rb_ancestor) ? NULL : &ancestor, NIL_P(rb_theirs) ? NULL : &ours, NIL_P(rb_ours) ? NULL : &theirs); rugged_exception_check(error); return Qnil; }
void test_index_conflicts__add(void) { git_index_entry ancestor_entry, our_entry, their_entry; cl_assert(git_index_entrycount(repo_index) == 8); memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); ancestor_entry.path = "test-one.txt"; ancestor_entry.flags |= (1 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID); our_entry.path = "test-one.txt"; ancestor_entry.flags |= (2 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&our_entry.id, TEST_OUR_OID); their_entry.path = "test-one.txt"; ancestor_entry.flags |= (3 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&their_entry.id, TEST_THEIR_OID); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); cl_assert(git_index_entrycount(repo_index) == 11); }
void test_index_conflicts__add_fixes_incorrect_stage(void) { git_index_entry ancestor_entry, our_entry, their_entry; const git_index_entry *conflict_entry[3]; cl_assert(git_index_entrycount(repo_index) == 8); memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); ancestor_entry.path = "test-one.txt"; ancestor_entry.flags |= (3 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID); our_entry.path = "test-one.txt"; ancestor_entry.flags |= (1 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&our_entry.id, TEST_OUR_OID); their_entry.path = "test-one.txt"; ancestor_entry.flags |= (2 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&their_entry.id, TEST_THEIR_OID); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); cl_assert(git_index_entrycount(repo_index) == 11); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt")); cl_assert(git_index_entry_stage(conflict_entry[0]) == 1); cl_assert(git_index_entry_stage(conflict_entry[1]) == 2); cl_assert(git_index_entry_stage(conflict_entry[2]) == 3); }
void test_index_conflicts__partial(void) { git_index_entry ancestor_entry, our_entry, their_entry; const git_index_entry *conflict_entry[3]; cl_assert(git_index_entrycount(repo_index) == 8); memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); ancestor_entry.path = "test-one.txt"; ancestor_entry.flags |= (1 << GIT_IDXENTRY_STAGESHIFT); git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, NULL, NULL)); cl_assert(git_index_entrycount(repo_index) == 9); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt")); cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id); cl_assert(conflict_entry[1] == NULL); cl_assert(conflict_entry[2] == NULL); }
static void add_conflicts(git_index *index, const char *filename) { git_index_entry ancestor_entry, our_entry, their_entry; static int conflict_idx = 0; char *ancestor_ids[] = { CONFLICTS_ONE_ANCESTOR_OID, CONFLICTS_TWO_ANCESTOR_OID }; char *our_ids[] = { CONFLICTS_ONE_OUR_OID, CONFLICTS_TWO_OUR_OID }; char *their_ids[] = { CONFLICTS_ONE_THEIR_OID, CONFLICTS_TWO_THEIR_OID }; conflict_idx = (conflict_idx + 1) % 2; memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); ancestor_entry.path = filename; ancestor_entry.mode = 0100644; GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 1); git_oid_fromstr(&ancestor_entry.id, ancestor_ids[conflict_idx]); our_entry.path = filename; our_entry.mode = 0100644; GIT_IDXENTRY_STAGE_SET(&our_entry, 2); git_oid_fromstr(&our_entry.id, our_ids[conflict_idx]); their_entry.path = filename; their_entry.mode = 0100644; GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 2); git_oid_fromstr(&their_entry.id, their_ids[conflict_idx]); cl_git_pass(git_index_conflict_add(index, &ancestor_entry, &our_entry, &their_entry)); }
void test_index_conflicts__add_removes_stage_zero(void) { git_index_entry staged, ancestor_entry, our_entry, their_entry; const git_index_entry *conflict_entry[3]; cl_assert(git_index_entrycount(repo_index) == 8); memset(&staged, 0x0, sizeof(git_index_entry)); memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); staged.path = "test-one.txt"; staged.mode = 0100644; git_oid_fromstr(&staged.id, TEST_STAGED_OID); cl_git_pass(git_index_add(repo_index, &staged)); cl_assert(git_index_entrycount(repo_index) == 9); ancestor_entry.path = "test-one.txt"; ancestor_entry.mode = 0100644; GIT_IDXENTRY_STAGE_SET(&ancestor_entry, 3); git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID); our_entry.path = "test-one.txt"; our_entry.mode = 0100644; GIT_IDXENTRY_STAGE_SET(&our_entry, 1); git_oid_fromstr(&our_entry.id, TEST_OUR_OID); their_entry.path = "test-one.txt"; their_entry.mode = 0100644; GIT_IDXENTRY_STAGE_SET(&their_entry, 2); git_oid_fromstr(&their_entry.id, TEST_THEIR_OID); cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); cl_assert(git_index_entrycount(repo_index) == 11); cl_assert_equal_p(NULL, git_index_get_bypath(repo_index, "test-one.txt", 0)); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, "test-one.txt")); cl_assert_equal_oid(&ancestor_entry.id, &conflict_entry[0]->id); cl_assert_equal_i(1, git_index_entry_stage(conflict_entry[0])); cl_assert_equal_oid(&our_entry.id, &conflict_entry[1]->id); cl_assert_equal_i(2, git_index_entry_stage(conflict_entry[1])); cl_assert_equal_oid(&their_entry.id, &conflict_entry[2]->id); cl_assert_equal_i(3, git_index_entry_stage(conflict_entry[2])); }
void test_status_worktree__conflict_has_no_oid(void) { git_repository *repo = cl_git_sandbox_init("status"); git_index *index; git_index_entry entry = {{0}}; git_status_list *statuslist; const git_status_entry *status; git_oid zero_id = {{0}}; entry.mode = 0100644; entry.path = "modified_file"; git_oid_fromstr(&entry.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); cl_git_pass(git_repository_index(&index, repo)); cl_git_pass(git_index_conflict_add(index, &entry, &entry, &entry)); git_status_list_new(&statuslist, repo, NULL); cl_assert_equal_i(16, git_status_list_entrycount(statuslist)); status = git_status_byindex(statuslist, 2); cl_assert_equal_i(GIT_STATUS_CONFLICTED, status->status); cl_assert_equal_s("modified_file", status->head_to_index->old_file.path); cl_assert(!git_oid_equal(&zero_id, &status->head_to_index->old_file.id)); cl_assert(0 != status->head_to_index->old_file.mode); cl_assert_equal_s("modified_file", status->head_to_index->new_file.path); cl_assert_equal_oid(&zero_id, &status->head_to_index->new_file.id); cl_assert_equal_i(0, status->head_to_index->new_file.mode); cl_assert_equal_i(0, status->head_to_index->new_file.size); cl_assert_equal_s("modified_file", status->index_to_workdir->old_file.path); cl_assert_equal_oid(&zero_id, &status->index_to_workdir->old_file.id); cl_assert_equal_i(0, status->index_to_workdir->old_file.mode); cl_assert_equal_i(0, status->index_to_workdir->old_file.size); cl_assert_equal_s("modified_file", status->index_to_workdir->new_file.path); cl_assert( !git_oid_equal(&zero_id, &status->index_to_workdir->new_file.id) || !(status->index_to_workdir->new_file.flags & GIT_DIFF_FLAG_VALID_ID)); cl_assert(0 != status->index_to_workdir->new_file.mode); cl_assert(0 != status->index_to_workdir->new_file.size); git_index_free(index); git_status_list_free(statuslist); }
static void do_conflicted_diff(diff_expects *exp, unsigned long flags) { const char *a_commit = "26a125ee1bf"; /* the current HEAD */ git_tree *a = resolve_commit_oid_to_tree(g_repo, a_commit); git_diff_options opts = GIT_DIFF_OPTIONS_INIT; git_index_entry ancestor = {{0}}, ours = {{0}}, theirs = {{0}}; git_diff *diff = NULL; git_index *index; cl_assert(a); opts.context_lines = 1; opts.interhunk_lines = 1; opts.flags |= flags; memset(exp, 0, sizeof(diff_expects)); cl_git_pass(git_repository_index(&index, g_repo)); ancestor.path = ours.path = theirs.path = "staged_changes"; ancestor.mode = ours.mode = theirs.mode = GIT_FILEMODE_BLOB; git_oid_fromstr(&ancestor.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); git_oid_fromstr(&ours.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); git_oid_fromstr(&theirs.id, "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef"); cl_git_pass(git_index_conflict_add(index, &ancestor, &ours, &theirs)); cl_git_pass(git_diff_tree_to_index(&diff, g_repo, a, index, &opts)); cl_git_pass(git_diff_foreach( diff, diff_file_cb, diff_binary_cb, diff_hunk_cb, diff_line_cb, exp)); git_diff_free(diff); git_tree_free(a); git_index_free(index); }
void Index::addConflict(const IndexEntry& ancestor, const IndexEntry& our, const IndexEntry& their) { Exception::git2_assert(git_index_conflict_add(data(), ancestor.constData(), our.constData(), their.constData())); }
void test_index_conflicts__case_matters(void) { const git_index_entry *conflict_entry[3]; git_oid oid; const char *upper_case = "DIFFERS-IN-CASE.TXT"; const char *mixed_case = "Differs-In-Case.txt"; const char *correct_case; bool ignorecase = cl_repo_get_bool(repo, "core.ignorecase"); git_index_entry ancestor_entry, our_entry, their_entry; memset(&ancestor_entry, 0x0, sizeof(git_index_entry)); memset(&our_entry, 0x0, sizeof(git_index_entry)); memset(&their_entry, 0x0, sizeof(git_index_entry)); ancestor_entry.path = upper_case; GIT_IDXENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR); git_oid_fromstr(&ancestor_entry.id, CONFLICTS_ONE_ANCESTOR_OID); ancestor_entry.mode = GIT_FILEMODE_BLOB; our_entry.path = upper_case; GIT_IDXENTRY_STAGE_SET(&our_entry, GIT_INDEX_STAGE_OURS); git_oid_fromstr(&our_entry.id, CONFLICTS_ONE_OUR_OID); our_entry.mode = GIT_FILEMODE_BLOB; their_entry.path = upper_case; GIT_IDXENTRY_STAGE_SET(&their_entry, GIT_INDEX_STAGE_THEIRS); git_oid_fromstr(&their_entry.id, CONFLICTS_ONE_THEIR_OID); their_entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); ancestor_entry.path = mixed_case; GIT_IDXENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR); git_oid_fromstr(&ancestor_entry.id, CONFLICTS_TWO_ANCESTOR_OID); ancestor_entry.mode = GIT_FILEMODE_BLOB; our_entry.path = mixed_case; GIT_IDXENTRY_STAGE_SET(&ancestor_entry, GIT_INDEX_STAGE_ANCESTOR); git_oid_fromstr(&our_entry.id, CONFLICTS_TWO_OUR_OID); ancestor_entry.mode = GIT_FILEMODE_BLOB; their_entry.path = mixed_case; GIT_IDXENTRY_STAGE_SET(&their_entry, GIT_INDEX_STAGE_THEIRS); git_oid_fromstr(&their_entry.id, CONFLICTS_TWO_THEIR_OID); their_entry.mode = GIT_FILEMODE_BLOB; cl_git_pass(git_index_conflict_add(repo_index, &ancestor_entry, &our_entry, &their_entry)); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, upper_case)); /* * We inserted with mixed case last, so on a case-insensitive * fs we should get the mixed case. */ if (ignorecase) correct_case = mixed_case; else correct_case = upper_case; cl_assert_equal_s(correct_case, conflict_entry[0]->path); git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_ANCESTOR_OID : CONFLICTS_ONE_ANCESTOR_OID); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); cl_assert_equal_s(correct_case, conflict_entry[1]->path); git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_OUR_OID : CONFLICTS_ONE_OUR_OID); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); cl_assert_equal_s(correct_case, conflict_entry[2]->path); git_oid_fromstr(&oid, ignorecase ? CONFLICTS_TWO_THEIR_OID : CONFLICTS_ONE_THEIR_OID); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); cl_git_pass(git_index_conflict_get(&conflict_entry[0], &conflict_entry[1], &conflict_entry[2], repo_index, mixed_case)); cl_assert_equal_s(mixed_case, conflict_entry[0]->path); git_oid_fromstr(&oid, CONFLICTS_TWO_ANCESTOR_OID); cl_assert_equal_oid(&oid, &conflict_entry[0]->id); cl_assert_equal_s(mixed_case, conflict_entry[1]->path); git_oid_fromstr(&oid, CONFLICTS_TWO_OUR_OID); cl_assert_equal_oid(&oid, &conflict_entry[1]->id); cl_assert_equal_s(mixed_case, conflict_entry[2]->path); git_oid_fromstr(&oid, CONFLICTS_TWO_THEIR_OID); cl_assert_equal_oid(&oid, &conflict_entry[2]->id); }