Browse Source

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
stable-2.2
Robin Stocker 12 years ago
parent
commit
ac805874f7
  1. 21
      org.eclipse.jgit.test/tst/org/eclipse/jgit/api/PathCheckoutCommandTest.java
  2. 9
      org.eclipse.jgit/src/org/eclipse/jgit/api/CheckoutCommand.java

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

@ -47,11 +47,13 @@ import static org.junit.Assert.assertEquals;
import java.io.File;
import java.io.IOException;
import org.eclipse.jgit.api.errors.JGitInternalException;
import org.eclipse.jgit.dircache.DirCache;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.errors.NoWorkTreeException;
import org.eclipse.jgit.lib.ConfigConstants;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.RepositoryState;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.lib.StoredConfig;
import org.eclipse.jgit.revwalk.RevCommit;
@ -243,4 +245,23 @@ public class PathCheckoutCommandTest extends RepositoryTestCase {
assertEquals("1", read(test));
assertEquals("a", read(test2));
}
@Test(expected = JGitInternalException.class)
public void testCheckoutOfConflictingFileShouldThrow()
throws Exception {
// Setup
git.checkout().setCreateBranch(true).setName("conflict")
.setStartPoint(initialCommit).call();
writeTrashFile(FILE1, "Conflicting");
RevCommit conflict = git.commit().setAll(true)
.setMessage("Conflicting change").call();
git.checkout().setName("master").call();
git.merge().include(conflict).call();
assertEquals(RepositoryState.MERGING, db.getRepositoryState());
// Now check out the conflicting path
git.checkout().addPath(FILE1).call();
}
}

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

@ -64,6 +64,7 @@ import org.eclipse.jgit.dircache.DirCacheEditor.PathEdit;
import org.eclipse.jgit.dircache.DirCacheEntry;
import org.eclipse.jgit.dircache.DirCacheIterator;
import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.errors.UnmergedPathException;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.Constants;
@ -284,7 +285,8 @@ public class CheckoutCommand extends GitCommand<Ref> {
startWalk.setRecursive(true);
if (!checkoutAllPaths)
startWalk.setFilter(PathFilterGroup.createFromStrings(paths));
boolean checkoutIndex = startCommit == null && startPoint == null;
final boolean checkoutIndex = startCommit == null
&& startPoint == null;
if (!checkoutIndex)
startWalk.addTree(revWalk.parseCommit(getStartPoint())
.getTree());
@ -299,6 +301,11 @@ public class CheckoutCommand extends GitCommand<Ref> {
final FileMode mode = startWalk.getFileMode(0);
editor.add(new PathEdit(startWalk.getPathString()) {
public void apply(DirCacheEntry ent) {
if (checkoutIndex
&& ent.getStage() > DirCacheEntry.STAGE_0) {
UnmergedPathException e = new UnmergedPathException(ent);
throw new JGitInternalException(e.getMessage(), e);
}
ent.setObjectId(blobId);
ent.setFileMode(mode);
File file = new File(workTree, ent.getPathString());

Loading…
Cancel
Save