CheckoutCommand: Fix checking out ours/theirs when no base stage exists

In case of an add/add conflict, no base stage exists. The previous
implementation would skip over the entries because the condition
expected the base stage to always exist.

Change-Id: Ie2b3685d958c09b241991b74e6177401e8a1ebc9
Signed-off-by: Robin Stocker <robin@nibor.org>
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
index dbda852..eb092ad 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
@@ -43,6 +43,7 @@
 package org.eclipse.jgit.api;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
 
 import java.io.File;
 import java.io.IOException;
@@ -276,6 +277,39 @@ public void testCheckoutTheirs() throws Exception {
 		assertStageOneToThree(FILE1);
 	}
 
+	@Test
+	public void testCheckoutOursWhenNoBase() throws Exception {
+		String file = "added.txt";
+
+		git.checkout().setCreateBranch(true).setName("side")
+				.setStartPoint(initialCommit).call();
+		writeTrashFile(file, "Added on side");
+		git.add().addFilepattern(file).call();
+		RevCommit side = git.commit().setMessage("Commit on side").call();
+
+		git.checkout().setName("master").call();
+		writeTrashFile(file, "Added on master");
+		git.add().addFilepattern(file).call();
+		git.commit().setMessage("Commit on master").call();
+
+		git.merge().include(side).call();
+		assertEquals(RepositoryState.MERGING, db.getRepositoryState());
+
+		DirCache cache = DirCache.read(db.getIndexFile(), db.getFS());
+		assertEquals("Expected add/add file to not have base stage",
+				DirCacheEntry.STAGE_2, cache.getEntry(file).getStage());
+
+		assertTrue(read(file).startsWith("<<<<<<< HEAD"));
+
+		git.checkout().setStage(Stage.OURS).addPath(file).call();
+
+		assertEquals("Added on master", read(file));
+
+		cache = DirCache.read(db.getIndexFile(), db.getFS());
+		assertEquals("Expected conflict stages to still exist after checkout",
+				DirCacheEntry.STAGE_2, cache.getEntry(file).getStage());
+	}
+
 	@Test(expected = IllegalStateException.class)
 	public void testStageNotPossibleWithBranch() throws Exception {
 		git.checkout().setStage(Stage.OURS).setStartPoint("master").call();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
index 1820932..3787ac5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java
@@ -405,14 +405,17 @@ private void checkoutPathsFromIndex(TreeWalk treeWalk, DirCache dc)
 		DirCacheIterator dci = new DirCacheIterator(dc);
 		treeWalk.addTree(dci);
 
+		String previousPath = null;
+
 		final ObjectReader r = treeWalk.getObjectReader();
 		DirCacheEditor editor = dc.editor();
 		while (treeWalk.next()) {
-			DirCacheEntry entry = dci.getDirCacheEntry();
+			String path = treeWalk.getPathString();
 			// Only add one edit per path
-			if (entry != null && entry.getStage() > DirCacheEntry.STAGE_1)
+			if (path.equals(previousPath))
 				continue;
-			editor.add(new PathEdit(treeWalk.getPathString()) {
+
+			editor.add(new PathEdit(path) {
 				public void apply(DirCacheEntry ent) {
 					int stage = ent.getStage();
 					if (stage > DirCacheEntry.STAGE_0) {
@@ -429,6 +432,8 @@ public void apply(DirCacheEntry ent) {
 					}
 				}
 			});
+
+			previousPath = path;
 		}
 		editor.commit();
 	}