Commit ecd60a56 by Edward Thomson

conflicts: when adding conflicts, remove staged

When adding a conflict for some path, remove the staged entry.
Otherwise, an illegal index (with both stage 0 and high-stage
entries) would result.
parent 1b6c26db
...@@ -49,6 +49,8 @@ support for HTTPS connections insead of OpenSSL. ...@@ -49,6 +49,8 @@ support for HTTPS connections insead of OpenSSL.
the error message, which allows you to get the "repository not the error message, which allows you to get the "repository not
found" messages. found" messages.
* `git_index_conflict_add()` will remove staged entries that exist for
conflicted paths.
### API additions ### API additions
......
...@@ -631,7 +631,8 @@ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *pat ...@@ -631,7 +631,8 @@ GIT_EXTERN(int) git_index_find(size_t *at_pos, git_index *index, const char *pat
/**@{*/ /**@{*/
/** /**
* Add or update index entries to represent a conflict * Add or update index entries to represent a conflict. Any staged
* entries that exist at the given paths will be removed.
* *
* The entries are the entries from the tree included in the merge. Any * The entries are the entries from the tree included in the merge. Any
* entry may be null to indicate that that file was not present in the * entry may be null to indicate that that file was not present in the
......
...@@ -1314,6 +1314,21 @@ int git_index_conflict_add(git_index *index, ...@@ -1314,6 +1314,21 @@ int git_index_conflict_add(git_index *index,
(ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0) (ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0)
goto on_error; goto on_error;
/* Remove existing index entries for each path */
for (i = 0; i < 3; i++) {
if (entries[i] == NULL)
continue;
if ((ret = git_index_remove(index, entries[i]->path, 0)) != 0) {
if (ret != GIT_ENOTFOUND)
goto on_error;
giterr_clear();
ret = 0;
}
}
/* Add the conflict entries */
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
if (entries[i] == NULL) if (entries[i] == NULL)
continue; continue;
...@@ -1321,7 +1336,7 @@ int git_index_conflict_add(git_index *index, ...@@ -1321,7 +1336,7 @@ int git_index_conflict_add(git_index *index,
/* Make sure stage is correct */ /* Make sure stage is correct */
GIT_IDXENTRY_STAGE_SET(entries[i], i + 1); GIT_IDXENTRY_STAGE_SET(entries[i], i + 1);
if ((ret = index_insert(index, &entries[i], 1, true)) < 0) if ((ret = index_insert(index, &entries[i], 0, true)) < 0)
goto on_error; goto on_error;
entries[i] = NULL; /* don't free if later entry fails */ entries[i] = NULL; /* don't free if later entry fails */
......
...@@ -16,6 +16,7 @@ static git_index *repo_index; ...@@ -16,6 +16,7 @@ static git_index *repo_index;
#define CONFLICTS_TWO_OUR_OID "8b3f43d2402825c200f835ca1762413e386fd0b2" #define CONFLICTS_TWO_OUR_OID "8b3f43d2402825c200f835ca1762413e386fd0b2"
#define CONFLICTS_TWO_THEIR_OID "220bd62631c8cf7a83ef39c6b94595f00517211e" #define CONFLICTS_TWO_THEIR_OID "220bd62631c8cf7a83ef39c6b94595f00517211e"
#define TEST_STAGED_OID "beefdadafeedabedcafedeedbabedeadbeaddeaf"
#define TEST_ANCESTOR_OID "f00ff00ff00ff00ff00ff00ff00ff00ff00ff00f" #define TEST_ANCESTOR_OID "f00ff00ff00ff00ff00ff00ff00ff00ff00ff00f"
#define TEST_OUR_OID "b44bb44bb44bb44bb44bb44bb44bb44bb44bb44b" #define TEST_OUR_OID "b44bb44bb44bb44bb44bb44bb44bb44bb44bb44b"
#define TEST_THEIR_OID "0123456789abcdef0123456789abcdef01234567" #define TEST_THEIR_OID "0123456789abcdef0123456789abcdef01234567"
...@@ -96,6 +97,55 @@ void test_index_conflicts__add_fixes_incorrect_stage(void) ...@@ -96,6 +97,55 @@ void test_index_conflicts__add_fixes_incorrect_stage(void)
cl_assert(git_index_entry_stage(conflict_entry[2]) == 3); cl_assert(git_index_entry_stage(conflict_entry[2]) == 3);
} }
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.mode = 0100644;
staged.path = "test-one.txt";
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;
ancestor_entry.flags |= (3 << GIT_IDXENTRY_STAGESHIFT);
git_oid_fromstr(&ancestor_entry.id, TEST_ANCESTOR_OID);
our_entry.path = "test-one.txt";
our_entry.mode = 0100644;
our_entry.flags |= (1 << GIT_IDXENTRY_STAGESHIFT);
git_oid_fromstr(&our_entry.id, TEST_OUR_OID);
their_entry.path = "test-one.txt";
their_entry.mode = 0100644;
their_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_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_index_conflicts__get(void) void test_index_conflicts__get(void)
{ {
const git_index_entry *conflict_entry[3]; const git_index_entry *conflict_entry[3];
......
...@@ -634,7 +634,7 @@ void test_status_worktree__conflicted_item(void) ...@@ -634,7 +634,7 @@ void test_status_worktree__conflicted_item(void)
&our_entry, &their_entry)); &our_entry, &their_entry));
cl_git_pass(git_status_file(&status, repo, "modified_file")); cl_git_pass(git_status_file(&status, repo, "modified_file"));
cl_assert_equal_i(GIT_STATUS_WT_MODIFIED, status); cl_assert_equal_i(GIT_STATUS_INDEX_DELETED|GIT_STATUS_WT_NEW, status);
git_index_free(index); git_index_free(index);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment