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 a61b44eda..cfeba135c 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 @@ -575,6 +575,69 @@ public void testStopOnConflict() throws Exception { assertFalse(new File(db.getDirectory(), "rebase-merge").exists()); } + @Test + public void testStopOnConflictAndAbortWithDetachedHEAD() throws Exception { + // create file1 on master + RevCommit firstInMaster = writeFileAndCommit(FILE1, "Add file1", "1", + "2", "3"); + // change first line in master + writeFileAndCommit(FILE1, "change file1 in master", "1master", "2", "3"); + checkFile(FILE1, "1master", "2", "3"); + // create a topic branch based on second commit + createBranch(firstInMaster, "refs/heads/topic"); + checkoutBranch("refs/heads/topic"); + // we have the old content again + checkFile(FILE1, "1", "2", "3"); + + // add a line (non-conflicting) + writeFileAndCommit(FILE1, "add a line to file1 in topic", "1", "2", + "3", "topic4"); + + // change first line (conflicting) + RevCommit conflicting = writeFileAndCommit(FILE1, + "change file1 in topic", "1topic", "2", "3", "topic4"); + + RevCommit lastTopicCommit = writeFileAndCommit(FILE1, + "change file1 in topic again", "1topic", "2", "3", "topic4"); + + git.checkout().setName(lastTopicCommit.getName()).call(); + + RebaseResult res = git.rebase().setUpstream("refs/heads/master").call(); + assertEquals(Status.STOPPED, res.getStatus()); + assertEquals(conflicting, res.getCurrentCommit()); + checkFile(FILE1, + "<<<<<<< Upstream, based on master\n1master\n=======\n1topic", + ">>>>>>> e0d1dea change file1 in topic\n2\n3\ntopic4"); + + assertEquals(RepositoryState.REBASING_INTERACTIVE, + db.getRepositoryState()); + assertTrue(new File(db.getDirectory(), "rebase-merge").exists()); + // the first one should be included, so we should have left two picks in + // the file + assertEquals(1, countPicks()); + + // rebase should not succeed in this state + try { + git.rebase().setUpstream("refs/heads/master").call(); + fail("Expected exception was not thrown"); + } catch (WrongRepositoryStateException e) { + // expected + } + + // abort should reset to topic branch + res = git.rebase().setOperation(Operation.ABORT).call(); + assertEquals(res.getStatus(), Status.ABORTED); + assertEquals(lastTopicCommit.getName(), db.getFullBranch()); + checkFile(FILE1, "1topic", "2", "3", "topic4"); + RevWalk rw = new RevWalk(db); + assertEquals(lastTopicCommit, + rw.parseCommit(db.resolve(Constants.HEAD))); + assertEquals(RepositoryState.SAFE, db.getRepositoryState()); + + // rebase- dir in .git must be deleted + assertFalse(new File(db.getDirectory(), "rebase-merge").exists()); + } + @Test public void testStopOnConflictAndContinue() throws Exception { // create file1 on master 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 10b273a74..ac6f5487a 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -1101,24 +1101,29 @@ private RebaseResult abort(RebaseResult result) throws IOException, } try { String headName = rebaseState.readFile(HEAD_NAME); - if (headName.startsWith(Constants.R_REFS)) { monitor.beginTask(MessageFormat.format( JGitText.get().resettingHead, headName), ProgressMonitor.UNKNOWN); + Result res = null; + RefUpdate refUpdate = repo.updateRef(Constants.HEAD, false); + refUpdate.setRefLogMessage("rebase: aborting", false); //$NON-NLS-1$ + if (headName.startsWith(Constants.R_REFS)) { // update the HEAD - RefUpdate refUpdate = repo.updateRef(Constants.HEAD, false); - refUpdate.setRefLogMessage("rebase: aborting", false); //$NON-NLS-1$ - Result res = refUpdate.link(headName); - switch (res) { - case FAST_FORWARD: - case FORCED: - case NO_CHANGE: - break; - default: - throw new JGitInternalException( - JGitText.get().abortingRebaseFailed); - } + res = refUpdate.link(headName); + } else { + refUpdate.setNewObjectId(repo.readOrigHead()); + res = refUpdate.forceUpdate(); + + } + switch (res) { + case FAST_FORWARD: + case FORCED: + case NO_CHANGE: + break; + default: + throw new JGitInternalException( + JGitText.get().abortingRebaseFailed); } boolean stashConflicts = autoStashApply(); // cleanup the files