diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java index 0d38197d9..301d6be66 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CherryPickCommandTest.java @@ -100,41 +100,73 @@ private void doTestCherryPick(boolean noCommit) throws IOException, } } - @Test - public void testSequentialCherryPick() throws IOException, JGitInternalException, - GitAPIException { - try (Git git = new Git(db)) { - writeTrashFile("a", "first line\nsec. line\nthird line\n"); - git.add().addFilepattern("a").call(); - RevCommit firstCommit = git.commit().setMessage("create a").call(); + @Test + public void testSequentialCherryPick() + throws IOException, JGitInternalException, GitAPIException { + try (Git git = new Git(db)) { + writeTrashFile("a", "first line\nsec. line\nthird line\n"); + git.add().addFilepattern("a").call(); + RevCommit firstCommit = git.commit().setMessage("create a").call(); - writeTrashFile("a", "first line\nsec. line\nthird line\nfourth line\n"); - git.add().addFilepattern("a").call(); - RevCommit enlargingA = git.commit().setMessage("enlarged a").call(); + writeTrashFile("a", + "first line\nsec. line\nthird line\nfourth line\n"); + git.add().addFilepattern("a").call(); + RevCommit enlargingA = git.commit().setMessage("enlarged a").call(); - writeTrashFile("a", - "first line\nsecond line\nthird line\nfourth line\n"); - git.add().addFilepattern("a").call(); - RevCommit fixingA = git.commit().setMessage("fixed a").call(); + writeTrashFile("a", + "first line\nsecond line\nthird line\nfourth line\n"); + git.add().addFilepattern("a").call(); + RevCommit fixingA = git.commit().setMessage("fixed a").call(); - git.branchCreate().setName("side").setStartPoint(firstCommit).call(); - checkoutBranch("refs/heads/side"); + git.branchCreate().setName("side").setStartPoint(firstCommit) + .call(); + checkoutBranch("refs/heads/side"); - writeTrashFile("b", "nothing to do with a"); - git.add().addFilepattern("b").call(); - git.commit().setMessage("create b").call(); + writeTrashFile("b", "nothing to do with a"); + git.add().addFilepattern("b").call(); + git.commit().setMessage("create b").call(); - CherryPickResult result = git.cherryPick().include(enlargingA).include(fixingA).call(); - assertEquals(CherryPickResult.CherryPickStatus.OK, result.getStatus()); + CherryPickResult result = git.cherryPick().include(enlargingA) + .include(fixingA).call(); + assertEquals(CherryPickResult.CherryPickStatus.OK, + result.getStatus()); - Iterator history = git.log().call().iterator(); - assertEquals("fixed a", history.next().getFullMessage()); - assertEquals("enlarged a", history.next().getFullMessage()); - assertEquals("create b", history.next().getFullMessage()); - assertEquals("create a", history.next().getFullMessage()); - assertFalse(history.hasNext()); - } - } + Iterator history = git.log().call().iterator(); + assertEquals("fixed a", history.next().getFullMessage()); + assertEquals("enlarged a", history.next().getFullMessage()); + assertEquals("create b", history.next().getFullMessage()); + assertEquals("create a", history.next().getFullMessage()); + assertFalse(history.hasNext()); + } + } + + @Test + public void testRootCherryPick() + throws IOException, JGitInternalException, GitAPIException { + try (Git git = new Git(db)) { + writeTrashFile("a", "a"); + writeTrashFile("b", "b"); + git.add().addFilepattern("a").addFilepattern("b").call(); + RevCommit firstCommit = git.commit().setMessage("Create a and b") + .call(); + + git.checkout().setOrphan(true).setName("orphan").call(); + git.rm().addFilepattern("a").addFilepattern("b").call(); + writeTrashFile("a", "a"); + git.add().addFilepattern("a").call(); + git.commit().setMessage("Orphan a").call(); + + CherryPickResult result = git.cherryPick().include(firstCommit) + .call(); + assertEquals(CherryPickResult.CherryPickStatus.OK, + result.getStatus()); + + Iterator history = git.log().call().iterator(); + assertEquals("Create a and b", history.next().getFullMessage()); + assertEquals("Orphan a", history.next().getFullMessage()); + assertFalse(history.hasNext()); + } + } @Test public void testCherryPickDirtyIndex() throws Exception { diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java index ceba89d16..5f8c2b728 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -142,7 +142,9 @@ public CherryPickResult call() throws GitAPIException, NoMessageException, new String[] { "BASE", ourName, cherryPickName }); //$NON-NLS-1$ resolveMerger .setWorkingTreeIterator(new FileTreeIterator(repo)); - resolveMerger.setBase(srcParent.getTree()); + if (srcParent != null) { + resolveMerger.setBase(srcParent.getTree()); + } noProblems = merger.merge(newHead, srcCommit); failingPaths = resolveMerger.getFailingPaths(); unmergedPaths = resolveMerger.getUnmergedPaths(); @@ -217,12 +219,16 @@ private RevCommit getParentCommit(RevCommit srcCommit, RevWalk revWalk) IOException { final RevCommit srcParent; if (mainlineParentNumber == null) { - if (srcCommit.getParentCount() != 1) + int nOfParents = srcCommit.getParentCount(); + if (nOfParents == 0) { + return null; + } else if (nOfParents != 1) { throw new MultipleParentsNotAllowedException( MessageFormat.format( JGitText.get().canOnlyCherryPickCommitsWithOneParent, srcCommit.name(), Integer.valueOf(srcCommit.getParentCount()))); + } srcParent = srcCommit.getParent(0); } else { if (mainlineParentNumber.intValue() > srcCommit.getParentCount()) {