diff --git a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java index 559a6d5d4..4bdfa4d5b 100644 --- a/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java +++ b/org.eclipse.jgit.pgm.test/src/org/eclipse/jgit/lib/CLIRepositoryTestCase.java @@ -46,6 +46,7 @@ import java.io.File; import java.io.IOException; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; @@ -76,6 +77,18 @@ protected String[] execute(String... cmds) throws Exception { return result.toArray(new String[0]); } + /** + * @param link + * the path of the symbolic link to create + * @param target + * the target of the symbolic link + * @return the path to the symbolic link + * @throws Exception + */ + protected Path writeLink(String link, String target) throws Exception { + return JGitTestUtil.writeLink(db, link, target); + } + protected File writeTrashFile(final String name, final String data) throws IOException { return JGitTestUtil.writeTrashFile(db, name, data); diff --git a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java index 939a9f6fd..167d8ab51 100644 --- a/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java +++ b/org.eclipse.jgit.pgm.test/tst/org/eclipse/jgit/pgm/CheckoutTest.java @@ -44,9 +44,14 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; import java.io.File; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; import java.util.List; import org.eclipse.jgit.api.Git; @@ -59,7 +64,9 @@ import org.eclipse.jgit.treewalk.FileTreeIterator; import org.eclipse.jgit.treewalk.FileTreeIterator.FileEntry; import org.eclipse.jgit.treewalk.TreeWalk; +import org.eclipse.jgit.util.FS; import org.eclipse.jgit.util.FileUtils; +import org.junit.Assume; import org.junit.Test; public class CheckoutTest extends CLIRepositoryTestCase { @@ -578,4 +585,34 @@ public void testCheckoutPath() throws Exception { execute("git branch")); assertEquals("Hello world b", read(b)); } + + @Test + public void testCheckouSingleFile() throws Exception { + try (Git git = new Git(db)) { + File a = writeTrashFile("a", "file a"); + git.add().addFilepattern(".").call(); + git.commit().setMessage("commit file a").call(); + writeTrashFile("a", "b"); + assertEquals("b", read(a)); + assertEquals("[]", Arrays.toString(execute("git checkout -- a"))); + assertEquals("file a", read(a)); + } + } + + @Test + public void testCheckoutLink() throws Exception { + Assume.assumeTrue(FS.DETECTED.supportsSymlinks()); + try (Git git = new Git(db)) { + Path path = writeLink("a", "link_a"); + assertTrue(Files.isSymbolicLink(path)); + git.add().addFilepattern(".").call(); + git.commit().setMessage("commit link a").call(); + deleteTrashFile("a"); + writeTrashFile("a", "Hello world a"); + assertFalse(Files.isSymbolicLink(path)); + assertEquals("[]", Arrays.toString(execute("git checkout -- a"))); + assertEquals("link_a", FileUtils.readSymLink(path.toFile())); + assertTrue(Files.isSymbolicLink(path)); + } + } } diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java index 45794629e..94517dbf2 100644 --- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java +++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Checkout.java @@ -60,7 +60,7 @@ import org.eclipse.jgit.pgm.internal.CLIText; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Option; -import org.kohsuke.args4j.spi.StopOptionHandler; +import org.kohsuke.args4j.spi.RestOfArgumentsHandler; @Command(common = true, usage = "usage_checkout") class Checkout extends TextBuiltin { @@ -74,11 +74,10 @@ class Checkout extends TextBuiltin { @Option(name = "--orphan", usage = "usage_orphan") private boolean orphan = false; - @Argument(required = true, index = 0, metaVar = "metaVar_name", usage = "usage_checkout") + @Argument(required = false, index = 0, metaVar = "metaVar_name", usage = "usage_checkout") private String name; - @Argument(index = 1) - @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = StopOptionHandler.class) + @Option(name = "--", metaVar = "metaVar_paths", multiValued = true, handler = RestOfArgumentsHandler.class) private List paths = new ArrayList(); @Override