summaryrefslogtreecommitdiff
path: root/src/merge.c
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@microsoft.com>2014-01-29 13:14:00 -0800
committerEdward Thomson <ethomson@microsoft.com>2014-01-29 13:15:55 -0800
commit0972c59205a0cf29e75b45695cde5dc699983bc0 (patch)
tree78a48f50068edc95df150f8fe29fa19e20b9633b /src/merge.c
parentb747eb1445fa54675044b6d05e892904b517239c (diff)
downloadlibgit2-0972c59205a0cf29e75b45695cde5dc699983bc0.tar.gz
Two-phase index merging
When three-way merging indexes, we previously changed each path as we read them, which would lead to us adding an index entry for 'foo', then removing an index entry for 'foo/file'. With the new index requirements, this is not allowed. Removing entries in the merged index, then adding them, resolves this. In the previous example, we now remove 'foo/file' before adding 'foo'.
Diffstat (limited to 'src/merge.c')
-rw-r--r--src/merge.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/src/merge.c b/src/merge.c
index f4224955a..20cfc0e23 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -2398,12 +2398,21 @@ int git_merge__indexes(git_repository *repo, git_index *index_new)
goto done;
}
- /* Update the new index */
+ /* Remove removed items from the index */
git_vector_foreach(&paths, i, path) {
- if ((e = git_index_get_bypath(index_new, path, 0)) != NULL)
- error = git_index_add(index_repo, e);
- else
- error = git_index_remove(index_repo, path, 0);
+ if ((e = git_index_get_bypath(index_new, path, 0)) == NULL) {
+ if ((error = git_index_remove(index_repo, path, 0)) < 0 &&
+ error != GIT_ENOTFOUND)
+ goto done;
+ }
+ }
+
+ /* Add updated items to the index */
+ git_vector_foreach(&paths, i, path) {
+ if ((e = git_index_get_bypath(index_new, path, 0)) != NULL) {
+ if ((error = git_index_add(index_repo, e)) < 0)
+ goto done;
+ }
}
/* Add conflicts */