mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-06 17:10:59 +00:00
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.
This commit is contained in:
parent
1b6c26db97
commit
ecd60a56eb
@ -49,6 +49,8 @@ support for HTTPS connections insead of OpenSSL.
|
||||
the error message, which allows you to get the "repository not
|
||||
found" messages.
|
||||
|
||||
* `git_index_conflict_add()` will remove staged entries that exist for
|
||||
conflicted paths.
|
||||
|
||||
### API additions
|
||||
|
||||
|
@ -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
|
||||
* entry may be null to indicate that that file was not present in the
|
||||
|
17
src/index.c
17
src/index.c
@ -1314,6 +1314,21 @@ int git_index_conflict_add(git_index *index,
|
||||
(ret = index_entry_dup(&entries[2], INDEX_OWNER(index), their_entry)) < 0)
|
||||
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++) {
|
||||
if (entries[i] == NULL)
|
||||
continue;
|
||||
@ -1321,7 +1336,7 @@ int git_index_conflict_add(git_index *index,
|
||||
/* Make sure stage is correct */
|
||||
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;
|
||||
|
||||
entries[i] = NULL; /* don't free if later entry fails */
|
||||
|
@ -16,6 +16,7 @@ static git_index *repo_index;
|
||||
#define CONFLICTS_TWO_OUR_OID "8b3f43d2402825c200f835ca1762413e386fd0b2"
|
||||
#define CONFLICTS_TWO_THEIR_OID "220bd62631c8cf7a83ef39c6b94595f00517211e"
|
||||
|
||||
#define TEST_STAGED_OID "beefdadafeedabedcafedeedbabedeadbeaddeaf"
|
||||
#define TEST_ANCESTOR_OID "f00ff00ff00ff00ff00ff00ff00ff00ff00ff00f"
|
||||
#define TEST_OUR_OID "b44bb44bb44bb44bb44bb44bb44bb44bb44bb44b"
|
||||
#define TEST_THEIR_OID "0123456789abcdef0123456789abcdef01234567"
|
||||
@ -96,6 +97,55 @@ void test_index_conflicts__add_fixes_incorrect_stage(void)
|
||||
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)
|
||||
{
|
||||
const git_index_entry *conflict_entry[3];
|
||||
|
@ -634,7 +634,7 @@ void test_status_worktree__conflicted_item(void)
|
||||
&our_entry, &their_entry));
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user