ResolveMerger: do not content-merge gitlinks on del/mod conflicts

Previously ResolveMerger tried to make a fulltext merge entry in case
one of sides got deleted regardless of file mode. This is not
applicable for GITLINK type of entry. After this change it is
rendering appropriate merge result.

Signed-off-by: Demetr Starshov <dstarshov@google.com>
Change-Id: Ibdb4557bf8781bdb48bcee6529e37dc80582ed7e
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java
index 7ca1e8c..c850b4d 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/GitlinkMergeTest.java
@@ -27,7 +27,6 @@
 import org.eclipse.jgit.lib.PersonIdent;
 import org.eclipse.jgit.test.resources.SampleDataRepositoryTestCase;
 import org.eclipse.jgit.treewalk.TreeWalk;
-import org.junit.Ignore;
 import org.junit.Test;
 
 public class GitlinkMergeTest extends SampleDataRepositoryTestCase {
@@ -38,7 +37,6 @@
 	private static final String SUBMODULE_PATH = "submodule.link";
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_AddNew() throws Exception {
 		assertGitLinkValue(
 				testGitLink(null, null, LINK_ID3, newResolveMerger(), true),
@@ -46,20 +44,17 @@
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_Delete() throws Exception {
 		assertGitLinkDoesntExist(testGitLink(LINK_ID1, LINK_ID1, null,
 				newResolveMerger(), true));
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_UpdateDelete() throws Exception {
 		testGitLink(LINK_ID1, LINK_ID2, null, newResolveMerger(), false);
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_DeleteUpdate() throws Exception {
 		testGitLink(LINK_ID1, null, LINK_ID3, newResolveMerger(), false);
 	}
@@ -90,14 +85,12 @@
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_Delete_ignoreConflicts() throws Exception {
 		assertGitLinkDoesntExist(testGitLink(LINK_ID1, LINK_ID1, null,
 				newIgnoreConflictMerger(), true));
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_UpdateDelete_ignoreConflicts()
 			throws Exception {
 		assertGitLinkValue(testGitLink(LINK_ID1, LINK_ID2, null,
@@ -105,7 +98,6 @@
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_DeleteUpdate_ignoreConflicts()
 			throws Exception {
 		assertGitLinkDoesntExist(testGitLink(LINK_ID1, null, LINK_ID3,
@@ -299,7 +291,6 @@
 	}
 
 	@Test
-	@Ignore("Broken")
 	public void testGitLinkMerging_linkBlobDeleted() throws Exception {
 		// We changed a link to a blob, others has deleted this link.
 		DirCache treeB = db.readDirCache();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
index a88da65..6c217fd 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/merge/ResolveMerger.java
@@ -757,6 +757,7 @@
 				add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
 				add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
 				add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
+
 				// attribute merge issues are conflicts but not failures
 				unmergedPaths.add(tw.getPathString());
 				return true;
@@ -783,40 +784,55 @@
 			// OURS or THEIRS has been deleted
 			if (((modeO != 0 && !tw.idEqual(T_BASE, T_OURS)) || (modeT != 0 && !tw
 					.idEqual(T_BASE, T_THEIRS)))) {
-				MergeResult<RawText> result = contentMerge(base, ours, theirs,
-						attributes);
-
-				if (ignoreConflicts) {
-					// In case a conflict is detected the working tree file is
-					// again filled with new content (containing conflict
-					// markers). But also stage 0 of the index is filled with
-					// that content.
-					result.setContainsConflicts(false);
-					updateIndex(base, ours, theirs, result, attributes);
-				} else {
+				if (gitLinkMerging && ignoreConflicts) {
+					add(tw.getRawPath(), ours, DirCacheEntry.STAGE_0, EPOCH, 0);
+				} else if (gitLinkMerging) {
 					add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH, 0);
 					add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH, 0);
-					DirCacheEntry e = add(tw.getRawPath(), theirs,
-							DirCacheEntry.STAGE_3, EPOCH, 0);
+					add(tw.getRawPath(), theirs, DirCacheEntry.STAGE_3, EPOCH, 0);
+					MergeResult<SubmoduleConflict> result = createGitLinksMergeResult(
+							base, ours, theirs);
+					result.setContainsConflicts(true);
+					mergeResults.put(tw.getPathString(), result);
+					unmergedPaths.add(tw.getPathString());
+				} else {
+					MergeResult<RawText> result = contentMerge(base, ours,
+							theirs, attributes);
 
-					// OURS was deleted checkout THEIRS
-					if (modeO == 0) {
-						// Check worktree before checking out THEIRS
-						if (isWorktreeDirty(work, ourDce)) {
-							return false;
-						}
-						if (nonTree(modeT)) {
-							if (e != null) {
-								addToCheckout(tw.getPathString(), e,
-										attributes);
+					if (ignoreConflicts) {
+						// In case a conflict is detected the working tree file
+						// is again filled with new content (containing conflict
+						// markers). But also stage 0 of the index is filled
+						// with that content.
+						result.setContainsConflicts(false);
+						updateIndex(base, ours, theirs, result, attributes);
+					} else {
+						add(tw.getRawPath(), base, DirCacheEntry.STAGE_1, EPOCH,
+								0);
+						add(tw.getRawPath(), ours, DirCacheEntry.STAGE_2, EPOCH,
+								0);
+						DirCacheEntry e = add(tw.getRawPath(), theirs,
+								DirCacheEntry.STAGE_3, EPOCH, 0);
+
+						// OURS was deleted checkout THEIRS
+						if (modeO == 0) {
+							// Check worktree before checking out THEIRS
+							if (isWorktreeDirty(work, ourDce)) {
+								return false;
+							}
+							if (nonTree(modeT)) {
+								if (e != null) {
+									addToCheckout(tw.getPathString(), e,
+											attributes);
+								}
 							}
 						}
+
+						unmergedPaths.add(tw.getPathString());
+
+						// generate a MergeResult for the deleted file
+						mergeResults.put(tw.getPathString(), result);
 					}
-
-					unmergedPaths.add(tw.getPathString());
-
-					// generate a MergeResult for the deleted file
-					mergeResults.put(tw.getPathString(), result);
 				}
 			}
 		}