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 df7343580..a99933796 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 @@ -76,6 +76,18 @@ public class CherryPickCommandTest extends RepositoryTestCase { @Test public void testCherryPick() throws IOException, JGitInternalException, GitAPIException { + doTestCherryPick(false); + } + + @Test + public void testCherryPickNoCommit() throws IOException, + JGitInternalException, GitAPIException { + doTestCherryPick(true); + } + + private void doTestCherryPick(boolean noCommit) throws IOException, + JGitInternalException, + GitAPIException { Git git = new Git(db); writeTrashFile("a", "first line\nsec. line\nthird line\n"); @@ -102,13 +114,16 @@ public void testCherryPick() throws IOException, JGitInternalException, git.add().addFilepattern("a").call(); git.commit().setMessage("enhanced a").call(); - git.cherryPick().include(fixingA).call(); + CherryPickResult pickResult = git.cherryPick().include(fixingA) + .setNoCommit(noCommit).call(); + assertEquals(CherryPickStatus.OK, pickResult.getStatus()); assertFalse(new File(db.getWorkTree(), "b").exists()); checkFile(new File(db.getWorkTree(), "a"), "first line\nsecond line\nthird line\nfeature++\n"); Iterator history = git.log().call().iterator(); - assertEquals("fixed a", history.next().getFullMessage()); + if (!noCommit) + assertEquals("fixed a", history.next().getFullMessage()); assertEquals("enhanced a", history.next().getFullMessage()); assertEquals("create a", history.next().getFullMessage()); assertFalse(history.hasNext()); @@ -205,6 +220,35 @@ public void testCherryPickConflictResolution() throws Exception { assertEquals(RepositoryState.SAFE, db.getRepositoryState()); } + @Test + public void testCherryPickConflictResolutionNoCOmmit() throws Exception { + Git git = new Git(db); + RevCommit sideCommit = prepareCherryPick(git); + + CherryPickResult result = git.cherryPick().include(sideCommit.getId()) + .setNoCommit(true).call(); + + assertEquals(CherryPickStatus.CONFLICTING, result.getStatus()); + assertTrue(db.readDirCache().hasUnmergedPaths()); + String expected = "<<<<<<< master\na(master)\n=======\na(side)\n>>>>>>> 527460a side\n"; + assertEquals(expected, read("a")); + assertTrue(new File(db.getDirectory(), Constants.MERGE_MSG).exists()); + assertEquals("side\n\nConflicts:\n\ta\n", db.readMergeCommitMsg()); + assertFalse(new File(db.getDirectory(), Constants.CHERRY_PICK_HEAD) + .exists()); + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + + // Resolve + writeTrashFile("a", "a"); + git.add().addFilepattern("a").call(); + + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + + git.commit().setOnly("a").setMessage("resolve").call(); + + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + } + @Test public void testCherryPickConflictReset() throws Exception { Git git = new Git(db); 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 cf50160da..30dcaa5b6 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CherryPickCommand.java @@ -93,6 +93,8 @@ public class CherryPickCommand extends GitCommand { private Integer mainlineParentNumber; + private boolean noCommit = false; + /** * @param repo */ @@ -162,11 +164,12 @@ public CherryPickResult call() throws GitAPIException, NoMessageException, merger.getResultTreeId()); dco.setFailOnConflict(true); dco.checkout(); - newHead = new Git(getRepository()).commit() - .setMessage(srcCommit.getFullMessage()) - .setReflogComment(reflogPrefix + " " //$NON-NLS-1$ - + srcCommit.getShortMessage()) - .setAuthor(srcCommit.getAuthorIdent()).call(); + if (!noCommit) + newHead = new Git(getRepository()).commit() + .setMessage(srcCommit.getFullMessage()) + .setReflogComment(reflogPrefix + " " //$NON-NLS-1$ + + srcCommit.getShortMessage()) + .setAuthor(srcCommit.getAuthorIdent()).call(); cherryPickedRefs.add(src); } else { if (merger.failed()) @@ -178,7 +181,8 @@ public CherryPickResult call() throws GitAPIException, NoMessageException, .formatWithConflicts(srcCommit.getFullMessage(), merger.getUnmergedPaths()); - repo.writeCherryPickHead(srcCommit.getId()); + if (!noCommit) + repo.writeCherryPickHead(srcCommit.getId()); repo.writeMergeCommitMsg(message); return CherryPickResult.CONFLICT; @@ -303,6 +307,23 @@ public CherryPickCommand setMainlineParentNumber(int mainlineParentNumber) { return this; } + /** + * Allows cherry-picking changes without committing them. + *

+ * NOTE: The behavior of cherry-pick is undefined if you pick multiple + * commits or if HEAD does not match the index state before cherry-picking. + * + * @param noCommit + * true to cherry-pick without committing, false to commit after + * each pick (default) + * @return {@code this} + * @since 3.5 + */ + public CherryPickCommand setNoCommit(boolean noCommit) { + this.noCommit = noCommit; + return this; + } + private String calculateOurName(Ref headRef) { if (ourCommitName != null) return ourCommitName;