From 8eb4d926371edea2d58dc598e3ebcddacbdc326e Mon Sep 17 00:00:00 2001 From: Dariusz Luksza Date: Wed, 3 Oct 2012 10:01:54 +0200 Subject: Add support for rebase interactive 'edit' command The 'edit' command allows you to change arbitrary commit content and the message of any commit in the repository. Bug: 394577 Change-Id: I43a44782cdb10b29f13784fa75ab37fe5d4da01b Signed-off-by: Dariusz Luksza Signed-off-by: Chris Aniszczyk --- .../org/eclipse/jgit/api/RebaseCommandTest.java | 52 ++++++++++++++++++++++ .../src/org/eclipse/jgit/api/RebaseCommand.java | 27 ++++++++--- 2 files changed, 72 insertions(+), 7 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 07ce7606b1..ba97e905b3 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 @@ -1581,6 +1581,58 @@ public class RebaseCommandTest extends RepositoryTestCase { assertEquals("rewritten commit message", actualCommitMag); } + @Test + public void testRebaseInteractiveEdit() throws Exception { + // create file1 on master + writeTrashFile(FILE1, FILE1); + git.add().addFilepattern(FILE1).call(); + git.commit().setMessage("Add file1").call(); + assertTrue(new File(db.getWorkTree(), FILE1).exists()); + + // create file2 on master + writeTrashFile("file2", "file2"); + git.add().addFilepattern("file2").call(); + git.commit().setMessage("Add file2").call(); + assertTrue(new File(db.getWorkTree(), "file2").exists()); + + // update FILE1 on master + writeTrashFile(FILE1, "blah"); + git.add().addFilepattern(FILE1).call(); + git.commit().setMessage("updated file1 on master").call(); + + writeTrashFile("file2", "more change"); + git.add().addFilepattern("file2").call(); + git.commit().setMessage("update file2 on side").call(); + + RebaseResult res = git.rebase().setUpstream("HEAD~2") + .runInteractively(new InteractiveHandler() { + public void prepareSteps(List steps) { + steps.get(0).action = Action.EDIT; + } + + public String modifyCommitMessage(String commit) { + return ""; // not used + } + }).call(); + assertEquals(Status.STOPPED, res.getStatus()); + RevCommit toBeEditted = git.log().call().iterator().next(); + assertEquals("updated file1 on master", toBeEditted.getFullMessage()); + + // change file and commit with new commit message + writeTrashFile("file1", "edited"); + git.commit().setAll(true).setAmend(true) + .setMessage("edited commit message").call(); + // resume rebase + res = git.rebase().setOperation(Operation.CONTINUE).call(); + + checkFile(new File(db.getWorkTree(), "file1"), "edited"); + assertEquals(Status.OK, res.getStatus()); + Iterator logIterator = git.log().all().call().iterator(); + logIterator.next(); // skip first commit; + String actualCommitMag = logIterator.next().getShortMessage(); + assertEquals("edited commit message", actualCommitMag); + } + private File getTodoFile() { File todoFile = new File(db.getDirectory(), "rebase-merge/git-rebase-todo"); 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 ece861f7f5..3f99057f9f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/RebaseCommand.java @@ -143,6 +143,8 @@ public class RebaseCommand extends GitCommand { private static final String REBASE_HEAD = "head"; + private static final String AMEND = "amend"; + /** * The available operations */ @@ -240,7 +242,12 @@ public class RebaseCommand extends GitCommand { if (operation == Operation.CONTINUE) { newHead = continueRebase(); - if (newHead == null) { + File amendFile = new File(rebaseDir, AMEND); + boolean amendExists = amendFile.exists(); + if (amendExists) { + FileUtils.delete(amendFile); + } + if (newHead == null && !amendExists) { // continueRebase() returns null only if no commit was // neccessary. This means that no changes where left over // after resolving all conflicts. In this case, cgit stops @@ -331,6 +338,9 @@ public class RebaseCommand extends GitCommand { newHead = new Git(repo).commit().setMessage(newMessage) .setAmend(true).call(); continue; + case EDIT: + createFile(rebaseDir, AMEND, commitToPick.name()); + return stop(commitToPick); } } finally { monitor.endTask(); @@ -1070,7 +1080,9 @@ public class RebaseCommand extends GitCommand { /** Use commit */ PICK("pick", "p"), /** Use commit, but edit the commit message */ - REWORD("reword", "r"); // later add SQUASH, EDIT, etc. + REWORD("reword", "r"), + /** Use commit, but stop for amending */ + EDIT("edit", "e"); // later add SQUASH, FIXUP, etc. private final String token; @@ -1094,13 +1106,14 @@ public class RebaseCommand extends GitCommand { } static Action parse(String token) { - if (token.equals(PICK.token) || token.equals(PICK.shortToken)) - return PICK; - if (token.equals(REWORD.token) || token.equals(REWORD.shortToken)) - return REWORD; + for (Action action : Action.values()) { + if (action.token.equals(token) + || action.shortToken.equals(token)) + return action; + } throw new JGitInternalException(MessageFormat.format( JGitText.get().unknownOrUnsupportedCommand, token, - PICK.toToken())); + Action.values())); } } -- cgit v1.2.3