Commit 1403c61265e6e459676c605ae934e8a86b58266c

Tyrie Vella 2018-01-22T14:44:31

merge: virtual commit should be last argument to merge-base Our virtual commit must be the last argument to merge-base: since our algorithm pushes _both_ parents of the virtual commit, it needs to be the last argument, since merge-base: > Given three commits A, B and C, git merge-base A B C will compute the > merge base between A and a hypothetical commit M We want to calculate the merge base between the actual commit ("two") and the virtual commit ("one") - since one actually pushes its parents to the merge-base calculation, we need to calculate the merge base of "two" and the parents of one.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
diff --git a/src/merge.c b/src/merge.c
index 37c83ec..6c98d13 100644
--- a/src/merge.c
+++ b/src/merge.c
@@ -2271,8 +2271,14 @@ static int compute_base(
 	if (given_opts)
 		memcpy(&opts, given_opts, sizeof(git_merge_options));
 
-	if ((error = insert_head_ids(&head_ids, one)) < 0 ||
-		(error = insert_head_ids(&head_ids, two)) < 0 ||
+	/* With more than two commits, merge_bases_many finds the base of
+	 * the first commit and a hypothetical merge of the others. Since
+	 * "one" may itself be a virtual commit, which insert_head_ids
+	 * substitutes multiple ancestors for, it needs to be added
+	 * after "two" which is always a single real commit.
+	 */
+	if ((error = insert_head_ids(&head_ids, two)) < 0 ||
+		(error = insert_head_ids(&head_ids, one)) < 0 ||
 		(error = git_merge_bases_many(&bases, repo,
 			head_ids.size, head_ids.ptr)) < 0)
 		goto done;