diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java index f8e1e03b5..5fa2c8154 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitAndLogCommandTests.java @@ -238,4 +238,21 @@ public void testCommitRange() throws NoHeadException, NoMessageException, } assertEquals(l, -1); } + + @Test + public void testCommitAmend() throws NoHeadException, NoMessageException, + UnmergedPathException, ConcurrentRefUpdateException, + JGitInternalException, WrongRepositoryStateException { + Git git = new Git(db); + git.commit().setMessage("first comit").call(); // typo + git.commit().setAmend(true).setMessage("first commit").call(); + + Iterable commits = git.log().call(); + int c = 0; + for (RevCommit commit : commits) { + assertEquals("first commit", commit.getFullMessage()); + c++; + } + assertEquals(1, c); + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java index 3ec09d42f..8ebee4967 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -87,6 +87,8 @@ public class CommitCommand extends GitCommand { private boolean all; + private boolean amend; + /** * parents this commit should have. The current HEAD will be in this list * and also all commits mentioned in .git/MERGE_HEAD @@ -155,7 +157,15 @@ public RevCommit call() throws NoHeadException, NoMessageException, // determine the current HEAD and the commit it is referring to ObjectId headId = repo.resolve(Constants.HEAD + "^{commit}"); if (headId != null) - parents.add(0, headId); + if (amend) { + RevCommit previousCommit = new RevWalk(repo) + .parseCommit(headId); + RevCommit[] p = previousCommit.getParents(); + for (int i = 0; i < p.length; i++) + parents.add(0, p[i].getId()); + } else { + parents.add(0, headId); + } // lock the index DirCache index = repo.lockDirCache(); @@ -187,9 +197,10 @@ public RevCommit call() throws NoHeadException, NoMessageException, + revCommit.getShortMessage(), false); ru.setExpectedOldObjectId(headId); - Result rc = ru.update(); + Result rc = ru.forceUpdate(); switch (rc) { case NEW: + case FORCED: case FAST_FORWARD: { setCallable(false); if (state == RepositoryState.MERGING_RESOLVED) { @@ -387,4 +398,17 @@ public CommitCommand setAll(boolean all) { return this; } + /** + * Used to amend the tip of the current branch. If set to true, the previous + * commit will be amended. This is equivalent to --amend on the command + * line. + * + * @param amend + * @return {@code this} + */ + public CommitCommand setAmend(boolean amend) { + this.amend = amend; + return this; + } + }