summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Lay <stefan.lay@sap.com>2013-12-10 15:54:48 +0100
committerStefan Lay <stefan.lay@sap.com>2013-12-10 15:54:48 +0100
commite90438c0e867bd105334b75df3a6d640ef8dab01 (patch)
tree93cfb6f300015b33f76d97f5e16a211a0d325cd7
parent162a5c4c89b289af3755a2f26843cdf908e93c50 (diff)
downloadjgit-e90438c0e867bd105334b75df3a6d640ef8dab01.tar.gz
jgit-e90438c0e867bd105334b75df3a6d640ef8dab01.zip
Fix aborting rebase with detached head
Bug: 423670 Change-Id: Ia6052867f85d4974c4f60ee5a6c820501e8d2427
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java63
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java31
2 files changed, 81 insertions, 13 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 a61b44eda8..cfeba135ca 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
@@ -576,6 +576,69 @@ public class RebaseCommandTest extends RepositoryTestCase {
}
@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
RevCommit firstInMaster = writeFileAndCommit(FILE1, "Add file1", "1",
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 10b273a744..ac6f5487a1 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 @@ public class RebaseCommand extends GitCommand<RebaseResult> {
}
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