Skip to content

Commit ac80587

Browse files
committed
Refuse to checkout unmerged paths from index
Without this check, the checkout was done but the result was a "both deleted" status when inspecting it with C Git. Found this while working on bug 390147. Change-Id: Ic3693f2c651827239e838bf7f37da842a7ae9707
1 parent eb5b506 commit ac80587

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,13 @@
4747
import java.io.File;
4848
import java.io.IOException;
4949

50+
import org.eclipse.jgit.api.errors.JGitInternalException;
5051
import org.eclipse.jgit.dircache.DirCache;
5152
import org.eclipse.jgit.dircache.DirCacheEntry;
5253
import org.eclipse.jgit.errors.NoWorkTreeException;
5354
import org.eclipse.jgit.lib.ConfigConstants;
5455
import org.eclipse.jgit.lib.ObjectReader;
56+
import org.eclipse.jgit.lib.RepositoryState;
5557
import org.eclipse.jgit.lib.RepositoryTestCase;
5658
import org.eclipse.jgit.lib.StoredConfig;
5759
import org.eclipse.jgit.revwalk.RevCommit;
@@ -243,4 +245,23 @@ public void testCheckoutRepository() throws Exception {
243245
assertEquals("1", read(test));
244246
assertEquals("a", read(test2));
245247
}
248+
249+
@Test(expected = JGitInternalException.class)
250+
public void testCheckoutOfConflictingFileShouldThrow()
251+
throws Exception {
252+
// Setup
253+
git.checkout().setCreateBranch(true).setName("conflict")
254+
.setStartPoint(initialCommit).call();
255+
writeTrashFile(FILE1, "Conflicting");
256+
RevCommit conflict = git.commit().setAll(true)
257+
.setMessage("Conflicting change").call();
258+
259+
git.checkout().setName("master").call();
260+
261+
git.merge().include(conflict).call();
262+
assertEquals(RepositoryState.MERGING, db.getRepositoryState());
263+
264+
// Now check out the conflicting path
265+
git.checkout().addPath(FILE1).call();
266+
}
246267
}

org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
import org.eclipse.jgit.dircache.DirCacheEntry;
6565
import org.eclipse.jgit.dircache.DirCacheIterator;
6666
import org.eclipse.jgit.errors.AmbiguousObjectException;
67+
import org.eclipse.jgit.errors.UnmergedPathException;
6768
import org.eclipse.jgit.internal.JGitText;
6869
import org.eclipse.jgit.lib.AnyObjectId;
6970
import org.eclipse.jgit.lib.Constants;
@@ -284,7 +285,8 @@ protected CheckoutCommand checkoutPaths() throws IOException,
284285
startWalk.setRecursive(true);
285286
if (!checkoutAllPaths)
286287
startWalk.setFilter(PathFilterGroup.createFromStrings(paths));
287-
boolean checkoutIndex = startCommit == null && startPoint == null;
288+
final boolean checkoutIndex = startCommit == null
289+
&& startPoint == null;
288290
if (!checkoutIndex)
289291
startWalk.addTree(revWalk.parseCommit(getStartPoint())
290292
.getTree());
@@ -299,6 +301,11 @@ protected CheckoutCommand checkoutPaths() throws IOException,
299301
final FileMode mode = startWalk.getFileMode(0);
300302
editor.add(new PathEdit(startWalk.getPathString()) {
301303
public void apply(DirCacheEntry ent) {
304+
if (checkoutIndex
305+
&& ent.getStage() > DirCacheEntry.STAGE_0) {
306+
UnmergedPathException e = new UnmergedPathException(ent);
307+
throw new JGitInternalException(e.getMessage(), e);
308+
}
302309
ent.setObjectId(blobId);
303310
ent.setFileMode(mode);
304311
File file = new File(workTree, ent.getPathString());

0 commit comments

Comments
 (0)