]> source.dussan.org Git - jgit.git/commitdiff
Fix aborting rebase with detached head 86/19586/1
authorStefan Lay <stefan.lay@sap.com>
Tue, 10 Dec 2013 14:54:48 +0000 (15:54 +0100)
committerStefan Lay <stefan.lay@sap.com>
Tue, 10 Dec 2013 14:54:48 +0000 (15:54 +0100)
Bug: 423670
Change-Id: Ia6052867f85d4974c4f60ee5a6c820501e8d2427

org.eclipse.jgit.test/tst/org/eclipse/jgit/api/RebaseCommandTest.java
org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java

index a61b44eda8d4d0df12b649a965c75de46861e1f9..cfeba135ca7f66e1540c3c2af5e19f6bfec28e52 100644 (file)
@@ -575,6 +575,69 @@ public class RebaseCommandTest extends RepositoryTestCase {
                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
index 10b273a7447602ebcc728b52f5264c8616970070..ac6f5487a19639832d87669a1a56fcedef8bc10c 100644 (file)
@@ -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