From 2d24816b4611a7392617855f497f81f385092f34 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Thu, 6 Nov 2014 18:49:37 -0500 Subject: [PATCH] checkout_index: Remove stage 0 when checking out conflicts --- src/checkout.c | 20 ++++++++++++++--- tests/checkout/index.c | 49 +++++++++++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/checkout.c b/src/checkout.c index 8ffd40d5d..8203c39ea 100644 --- a/src/checkout.c +++ b/src/checkout.c @@ -1912,6 +1912,20 @@ done: return error; } +static int checkout_conflict_add( + checkout_data *data, + const git_index_entry *conflict) +{ + int error = git_index_remove(data->index, conflict->path, 0); + + if (error == GIT_ENOTFOUND) + giterr_clear(); + else if (error < 0) + return error; + + return git_index_add(data->index, conflict); +} + static int checkout_conflict_update_index( checkout_data *data, checkout_conflictdata *conflict) @@ -1919,13 +1933,13 @@ static int checkout_conflict_update_index( int error = 0; if (conflict->ancestor) - error = git_index_add(data->index, conflict->ancestor); + error = checkout_conflict_add(data, conflict->ancestor); if (!error && conflict->ours) - error = git_index_add(data->index, conflict->ours); + error = checkout_conflict_add(data, conflict->ours); if (!error && conflict->theirs) - error = git_index_add(data->index, conflict->theirs); + error = checkout_conflict_add(data, conflict->theirs); return error; } diff --git a/tests/checkout/index.c b/tests/checkout/index.c index 3c01e2411..f94556214 100644 --- a/tests/checkout/index.c +++ b/tests/checkout/index.c @@ -619,17 +619,14 @@ void test_checkout_index__can_get_repo_from_index(void) git_index_free(index); } -static void add_conflict(void) +static void add_conflict(git_index *index, const char *path) { - git_index *index; git_index_entry entry; memset(&entry, 0, sizeof(git_index_entry)); - cl_git_pass(git_repository_index(&index, g_repo)); - entry.mode = 0100644; - entry.path = "conflicting.txt"; + entry.path = path; git_oid_fromstr(&entry.id, "d427e0b2e138501a3d15cc376077a3631e15bd46"); entry.flags = (1 << GIT_IDXENTRY_STAGESHIFT); @@ -642,17 +639,19 @@ static void add_conflict(void) git_oid_fromstr(&entry.id, "2bd0a343aeef7a2cf0d158478966a6e587ff3863"); entry.flags = (3 << GIT_IDXENTRY_STAGESHIFT); cl_git_pass(git_index_add(index, &entry)); - - cl_git_pass(git_index_write(index)); - git_index_free(index); } void test_checkout_index__writes_conflict_file(void) { + git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_buf conflicting_buf = GIT_BUF_INIT; - add_conflict(); + cl_git_pass(git_repository_index(&index, g_repo)); + + add_conflict(index, "conflicting.txt"); + cl_git_pass(git_index_write(index)); + cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt")); @@ -663,18 +662,46 @@ void test_checkout_index__writes_conflict_file(void) "this file is changed in branch and master\n" ">>>>>>> theirs\n") == 0); git_buf_free(&conflicting_buf); + + git_index_free(index); +} + +void test_checkout_index__adding_conflict_removes_stage_0(void) +{ + git_index *new_index, *index; + git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; + + cl_git_pass(git_index_new(&new_index)); + + add_conflict(new_index, "new.txt"); + cl_git_pass(git_checkout_index(g_repo, new_index, &opts)); + + cl_git_pass(git_repository_index(&index, g_repo)); + + cl_assert(git_index_get_bypath(index, "new.txt", 0) == NULL); + cl_assert(git_index_get_bypath(index, "new.txt", 1) != NULL); + cl_assert(git_index_get_bypath(index, "new.txt", 2) != NULL); + cl_assert(git_index_get_bypath(index, "new.txt", 3) != NULL); + + git_index_free(index); + git_index_free(new_index); } void test_checkout_index__conflicts_honor_coreautocrlf(void) { #ifdef GIT_WIN32 + git_index *index; git_checkout_options opts = GIT_CHECKOUT_OPTIONS_INIT; git_buf conflicting_buf = GIT_BUF_INIT; cl_git_pass(p_unlink("./testrepo/.gitattributes")); cl_repo_set_bool(g_repo, "core.autocrlf", true); - add_conflict(); + cl_git_pass(git_repository_index(&index, g_repo)); + + add_conflict(index, "conflicting.txt"); + cl_git_pass(git_index_write(index)); + cl_git_pass(git_checkout_index(g_repo, NULL, &opts)); cl_git_pass(git_futils_readbuffer(&conflicting_buf, "testrepo/conflicting.txt")); @@ -685,5 +712,7 @@ void test_checkout_index__conflicts_honor_coreautocrlf(void) "this file is changed in branch and master\r\n" ">>>>>>> theirs\r\n") == 0); git_buf_free(&conflicting_buf); + + git_index_free(index); #endif }