Commit 0972c59205a0cf29e75b45695cde5dc699983bc0

Edward Thomson 2014-01-29T13:14:00

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'.

diff --git a/src/merge.c b/src/merge.c
index f422495..20cfc0e 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 */