From 0972c59205a0cf29e75b45695cde5dc699983bc0 Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Wed, 29 Jan 2014 13:14:00 -0800 Subject: [PATCH] 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'. --- src/merge.c | 19 ++++++++++++++----- 1 file 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 */