From cf846cfb0b2ceb65749561a0ea1cbbc0904a2ee9 Mon Sep 17 00:00:00 2001 From: Bernard Leach Date: Mon, 23 May 2011 00:20:32 +1000 Subject: [PATCH] Remove rebase temporary files on checkout failure A checkout conflict during rebase setup should leave the repository in SAFE state which means ensuring that the rebase temporary files need to be removed. Bug: 346813 Change-Id: If8b758fde73ed5a452a99a195a844825a03bae1a Signed-off-by: Chris Aniszczyk --- .../eclipse/jgit/api/RebaseCommandTest.java | 41 ++++++++++++++++++- .../org/eclipse/jgit/api/RebaseCommand.java | 11 ++++- 2 files changed, 48 insertions(+), 4 deletions(-) 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 {