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 9197ac998..672f4d86a 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 @@ -164,7 +164,7 @@ public class RebaseCommandTest extends RepositoryTestCase { * Create the following commits and then attempt to rebase topic onto * master. This will fail as the cherry-pick list C, D, E an F contains * a merge commit (F). - * + * *
* A - B (master) * \ @@ -1053,7 +1053,7 @@ public class RebaseCommandTest extends RepositoryTestCase { // checkout topic branch / modify file2 and add checkoutBranch("refs/heads/topic"); - writeTrashFile("file2", "uncommitted file2"); + File uncommittedFile = writeTrashFile("file2", "uncommitted file2"); git.add().addFilepattern("file2").call(); // do not commit @@ -1067,6 +1067,9 @@ public class RebaseCommandTest extends RepositoryTestCase { assertNotNull(exception); assertEquals("Checkout conflict with files: \nfile2", exception.getMessage()); + + checkFile(uncommittedFile, "uncommitted file2"); + assertEquals(RepositoryState.SAFE, git.getRepository().getRepositoryState()); } @Test @@ -1375,4 +1378,38 @@ public class RebaseCommandTest extends RepositoryTestCase { checkFile(new File(db.getWorkTree(), "file2"), "more change"); assertEquals(Status.FAST_FORWARD, res.getStatus()); } + + @Test + public void testRebaseShouldLeaveWorkspaceUntouchedWithUnstagedChangesConflict() + throws Exception { + writeTrashFile(FILE1, "initial file"); + git.add().addFilepattern(FILE1).call(); + RevCommit initial = git.commit().setMessage("initial commit").call(); + createBranch(initial, "refs/heads/side"); + + writeTrashFile(FILE1, "updated file"); + git.add().addFilepattern(FILE1).call(); + git.commit().setMessage("updated FILE1 on master").call(); + + // switch to side, modify the file + checkoutBranch("refs/heads/side"); + writeTrashFile(FILE1, "side update"); + git.add().addFilepattern(FILE1).call(); + git.commit().setMessage("updated FILE1 on side").call(); + + File theFile = writeTrashFile(FILE1, "dirty the file"); + + // and attempt to rebase + try { + RebaseResult rebaseResult = git.rebase() + .setUpstream("refs/heads/master").call(); + fail("Checkout with conflict should have occured, not " + + rebaseResult.getStatus()); + } catch (JGitInternalException e) { + checkFile(theFile, "dirty the file"); + } + + assertEquals(RepositoryState.SAFE, git.getRepository() + .getRepositoryState()); + } } 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 114ef03a3..1503857ca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -595,7 +595,13 @@ public class RebaseCommand extends GitCommand{ // we rewind to the upstream commit monitor.beginTask(MessageFormat.format(JGitText.get().rewinding, upstreamCommit.getShortMessage()), ProgressMonitor.UNKNOWN); - checkoutCommit(upstreamCommit); + boolean checkoutOk = false; + try { + checkoutOk = checkoutCommit(upstreamCommit); + } finally { + if (!checkoutOk) + FileUtils.delete(rebaseDir, FileUtils.RECURSIVE); + } monitor.endTask(); return null; @@ -771,7 +777,7 @@ public class RebaseCommand extends GitCommand { return RawParseUtils.decode(content, 0, end); } - private void checkoutCommit(RevCommit commit) throws IOException { + private boolean checkoutCommit(RevCommit commit) throws IOException { try { RevCommit head = walk.parseCommit(repo.resolve(Constants.HEAD)); DirCacheCheckout dco = new DirCacheCheckout(repo, head.getTree(), @@ -795,6 +801,7 @@ public class RebaseCommand extends GitCommand { walk.release(); monitor.endTask(); } + return true; } private List loadSteps() throws IOException {