Merge "Record failing paths in recursive merge."
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
index 11435b8..b1450ef 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/JGitText.properties
@@ -502,7 +502,7 @@
 mergeStrategyAlreadyExistsAsDefault=Merge strategy "{0}" already exists as a default strategy
 mergeStrategyDoesNotSupportHeads=merge strategy {0} does not support {1} heads to be merged into HEAD
 mergeUsingStrategyResultedInDescription=Merge of revisions {0} with base {1} using strategy {2} resulted in: {3}. {4}
-mergeRecursiveConflictsWhenMergingCommonAncestors=Multiple common ancestors were found and merging them resulted in a conflict: {0}, {1}
+mergeRecursiveConflictsWhenMergingCommonAncestors=Multiple common ancestors were found and merging them resulted in a conflict: {0}, {1}\nFailing paths: {2}
 mergeRecursiveTooManyMergeBasesFor = "More than {0} merge bases for:\n a {1}\n b {2} found:\n  count {3}"
 mergeToolNotGivenError=No merge tool provided and no defaults configured.
 mergeToolNullError=Parameter for merge tool cannot be null.
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
index 1162a61..24614f7 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/RecursiveMerger.java
@@ -22,6 +22,7 @@
 import java.util.Date;
 import java.util.List;
 import java.util.TimeZone;
+import java.util.stream.Collectors;
 
 import org.eclipse.jgit.dircache.DirCache;
 import org.eclipse.jgit.errors.IncorrectObjectTypeException;
@@ -185,12 +186,15 @@ protected RevCommit getBaseCommit(RevCommit a, RevCommit b, int callDepth)
 				if (mergeTrees(bcTree, currentBase.getTree(),
 						nextBase.getTree(), true))
 					currentBase = createCommitForTree(resultTree, parents);
-				else
+				else {
+					String failedPaths = failingPathsMessage();
 					throw new NoMergeBaseException(
 							NoMergeBaseException.MergeBaseFailureReason.CONFLICTS_DURING_MERGE_BASE_CALCULATION,
 							MessageFormat.format(
 									JGitText.get().mergeRecursiveConflictsWhenMergingCommonAncestors,
-									currentBase.getName(), nextBase.getName()));
+									currentBase.getName(), nextBase.getName(),
+									failedPaths));
+				}
 			}
 		} finally {
 			inCore = oldIncore;
@@ -236,4 +240,17 @@ private static PersonIdent mockAuthor(List<RevCommit> parents) {
 				new Date((time + 1) * 1000L),
 				TimeZone.getTimeZone("GMT+0000")); //$NON-NLS-1$
 	}
+
+	private String failingPathsMessage() {
+		int max = 25;
+		String failedPaths = failingPaths.entrySet().stream().limit(max)
+				.map(entry -> entry.getKey() + ":" + entry.getValue())
+				.collect(Collectors.joining("\n"));
+
+		if (failingPaths.size() > max) {
+			failedPaths = String.format("%s\n... (%s failing paths omitted)",
+					failedPaths, failingPaths.size() - max);
+		}
+		return failedPaths;
+	}
 }