diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java index 672f4d86a..648ef6f01 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java @@ -502,6 +502,55 @@ public void testStopOnConflictAndContinue() throws Exception { .getFullMessage()); } + @Test + public void testStopOnConflictAndContinueWithNoDeltaToMaster() + throws Exception { + // create file1 on master + RevCommit firstInMaster = writeFileAndCommit(FILE1, "Add file1", "1", + "2", "3"); + // change in master + writeFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3"); + + checkFile(FILE1, "1master", "2", "3"); + // create a topic branch based on the first commit + createBranch(firstInMaster, "refs/heads/topic"); + checkoutBranch("refs/heads/topic"); + // we have the old content again + checkFile(FILE1, "1", "2", "3"); + + // change first line (conflicting) + writeFileAndCommit(FILE1, + "change file1 in topic\n\nThis is conflicting", "1topic", "2", + "3", "4topic"); + + RebaseResult res = git.rebase().setUpstream("refs/heads/master").call(); + assertEquals(Status.STOPPED, res.getStatus()); + + // continue should throw a meaningful exception + try { + res = git.rebase().setOperation(Operation.CONTINUE).call(); + fail("Expected Exception not thrown"); + } catch (UnmergedPathsException e) { + // expected + } + + // merge the file; the second topic commit should go through + writeFileAndAdd(FILE1, "1master", "2", "3"); + + res = git.rebase().setOperation(Operation.CONTINUE).call(); + assertNotNull(res); + assertEquals(Status.NOTHING_TO_COMMIT, res.getStatus()); + assertEquals(RepositoryState.REBASING_INTERACTIVE, + db.getRepositoryState()); + + git.rebase().setOperation(Operation.SKIP).call(); + + ObjectId headId = db.resolve(Constants.HEAD); + RevWalk rw = new RevWalk(db); + RevCommit rc = rw.parseCommit(headId); + assertEquals("change file1 in master", rc.getFullMessage()); + } + @Test public void testStopOnConflictAndFailContinueIfFileIsDirty() throws Exception { @@ -775,8 +824,15 @@ public void testStopOnConflictCommitAndContinue() throws Exception { res = git.rebase().setOperation(Operation.CONTINUE).call(); assertNotNull(res); - assertEquals(Status.OK, res.getStatus()); - assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + + // nothing to commit. this leaves the repo state in rebase, so that the + // user can decide what to do. if he accidentally committed, reset soft, + // and continue, if he really has nothing to commit, skip. + assertEquals(Status.NOTHING_TO_COMMIT, res.getStatus()); + assertEquals(RepositoryState.REBASING_INTERACTIVE, + db.getRepositoryState()); + + git.rebase().setOperation(Operation.SKIP).call(); ObjectId headId = db.resolve(Constants.HEAD); RevWalk rw = new RevWalk(db); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java index ae73cacbe..936f5cab8 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -220,9 +220,19 @@ public RebaseResult call() throws NoHeadException, RefNotFoundException, if (monitor.isCancelled()) return abort(RebaseResult.ABORTED_RESULT); - if (operation == Operation.CONTINUE) + if (operation == Operation.CONTINUE) { newHead = continueRebase(); + if (newHead == null) { + // continueRebase() returns null only if no commit was + // neccessary. This means that no changes where left over + // after resolving all conflicts. In this case, cgit stops + // and displays a nice message to the user, telling him to + // either do changes or skip the commit instead of continue. + return RebaseResult.NOTHING_TO_COMMIT_RESULT; + } + } + if (operation == Operation.SKIP) newHead = checkoutCurrentHead(); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java index e389d9902..4739f1617 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseResult.java @@ -109,6 +109,16 @@ public boolean isSuccessful() { public boolean isSuccessful() { return true; } + }, + + /** + * Continue with nothing left to commit (possibly want skip). + */ + NOTHING_TO_COMMIT { + @Override + public boolean isSuccessful() { + return false; + } }; /** @@ -127,6 +137,9 @@ public boolean isSuccessful() { static final RebaseResult FAST_FORWARD_RESULT = new RebaseResult( Status.FAST_FORWARD); + static final RebaseResult NOTHING_TO_COMMIT_RESULT = new RebaseResult( + Status.NOTHING_TO_COMMIT); + private final Status status; private final RevCommit currentCommit;