diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java index 8084505c1..35de73e20 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/api/CommitCommandTest.java @@ -46,6 +46,7 @@ import org.eclipse.jgit.lib.ReflogEntry; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; +import org.eclipse.jgit.lib.CommitConfig.CleanupMode; import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.storage.file.FileBasedConfig; import org.eclipse.jgit.submodule.SubmoduleWalk; @@ -514,6 +515,62 @@ public void commitAmendWithAuthorShouldUseIt() throws Exception { } } + @Test + public void commitMessageVerbatim() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("file1", "file1"); + git.add().addFilepattern("file1").call(); + RevCommit committed = git.commit().setMessage("#initial commit") + .call(); + + assertEquals("#initial commit", committed.getFullMessage()); + } + } + + @Test + public void commitMessageStrip() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("file1", "file1"); + git.add().addFilepattern("file1").call(); + RevCommit committed = git.commit().setMessage( + "#Comment\ninitial commit\t\n\n commit body \n \t#another comment") + .setCleanupMode(CleanupMode.STRIP).call(); + + assertEquals("initial commit\n\n commit body", + committed.getFullMessage()); + } + } + + @Test + public void commitMessageDefault() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("file1", "file1"); + git.add().addFilepattern("file1").call(); + RevCommit committed = git.commit().setMessage( + "#Comment\ninitial commit\t\n\n commit body \n\n\n \t#another comment ") + .setCleanupMode(CleanupMode.DEFAULT).call(); + + assertEquals("initial commit\n\n commit body", + committed.getFullMessage()); + } + } + + @Test + public void commitMessageDefaultWhitespace() throws Exception { + try (Git git = new Git(db)) { + writeTrashFile("file1", "file1"); + git.add().addFilepattern("file1").call(); + RevCommit committed = git.commit().setMessage( + "#Comment\ninitial commit\t\n\n commit body \n\n\n \t#another comment ") + .setCleanupMode(CleanupMode.DEFAULT).setDefaultClean(false) + .call(); + + assertEquals( + "#Comment\ninitial commit\n\n commit body\n\n \t#another comment", + committed.getFullMessage()); + } + } + @Test public void commitEmptyCommits() throws Exception { try (Git git = new Git(db)) { 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 37f1d482a..7a591aa3b 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/CommitCommand.java @@ -19,6 +19,7 @@ import java.util.LinkedList; import java.util.List; +import org.eclipse.jgit.annotations.NonNull; import org.eclipse.jgit.api.errors.AbortedByHookException; import org.eclipse.jgit.api.errors.CanceledException; import org.eclipse.jgit.api.errors.ConcurrentRefUpdateException; @@ -46,6 +47,8 @@ import org.eclipse.jgit.hooks.PreCommitHook; import org.eclipse.jgit.internal.JGitText; import org.eclipse.jgit.lib.CommitBuilder; +import org.eclipse.jgit.lib.CommitConfig; +import org.eclipse.jgit.lib.CommitConfig.CleanupMode; import org.eclipse.jgit.lib.Constants; import org.eclipse.jgit.lib.FileMode; import org.eclipse.jgit.lib.GpgConfig; @@ -133,6 +136,12 @@ public class CommitCommand extends GitCommand { private CredentialsProvider credentialsProvider; + private @NonNull CleanupMode cleanupMode = CleanupMode.VERBATIM; + + private boolean cleanDefaultIsStrip = true; + + private Character commentChar; + /** * Constructor for CommitCommand * @@ -200,7 +209,7 @@ public RevCommit call() throws GitAPIException, AbortedByHookException, throw new WrongRepositoryStateException( JGitText.get().commitAmendOnInitialNotPossible); - if (headId != null) + if (headId != null) { if (amend) { RevCommit previousCommit = rw.parseCommit(headId); for (RevCommit p : previousCommit.getParents()) @@ -210,7 +219,7 @@ public RevCommit call() throws GitAPIException, AbortedByHookException, } else { parents.add(0, headId); } - + } if (!noVerify) { message = Hooks .commitMsg(repo, @@ -219,6 +228,19 @@ public RevCommit call() throws GitAPIException, AbortedByHookException, .setCommitMessage(message).call(); } + CommitConfig config = null; + if (CleanupMode.DEFAULT.equals(cleanupMode)) { + config = repo.getConfig().get(CommitConfig.KEY); + cleanupMode = config.resolve(cleanupMode, cleanDefaultIsStrip); + } + char comments; + if (commentChar == null) { + comments = '#'; // TODO use git config core.commentChar + } else { + comments = commentChar.charValue(); + } + message = CommitConfig.cleanText(message, cleanupMode, comments); + RevCommit revCommit; DirCache index = repo.lockDirCache(); try (ObjectInserter odi = repo.newObjectInserter()) { @@ -657,6 +679,57 @@ public CommitCommand setMessage(String message) { return this; } + /** + * Sets the {@link CleanupMode} to apply to the commit message. If not + * called, {@link CommitCommand} applies {@link CleanupMode#VERBATIM}. + * + * @param mode + * {@link CleanupMode} to set + * @return {@code this} + * @since 6.1 + */ + public CommitCommand setCleanupMode(@NonNull CleanupMode mode) { + checkCallable(); + this.cleanupMode = mode; + return this; + } + + /** + * Sets the default clean mode if {@link #setCleanupMode(CleanupMode) + * setCleanupMode(CleanupMode.DEFAULT)} is set and git config + * {@code commit.cleanup = default} or is not set. + * + * @param strip + * if {@code true}, default to {@link CleanupMode#STRIP}; + * otherwise default to {@link CleanupMode#WHITESPACE} + * @return {@code this} + * @since 6.1 + */ + public CommitCommand setDefaultClean(boolean strip) { + checkCallable(); + this.cleanDefaultIsStrip = strip; + return this; + } + + /** + * Sets the comment character to apply when cleaning a commit message. If + * {@code null} (the default) and the {@link #setCleanupMode(CleanupMode) + * clean-up mode} is {@link CleanupMode#STRIP} or + * {@link CleanupMode#SCISSORS}, the value of git config + * {@code core.commentChar} will be used. + * + * @param commentChar + * the comment character, or {@code null} to use the value from + * the git config + * @return {@code this} + * @since 6.1 + */ + public CommitCommand setCommentCharacter(Character commentChar) { + checkCallable(); + this.commentChar = commentChar; + return this; + } + /** * Set whether to allow to create an empty commit * @@ -806,7 +879,7 @@ public CommitCommand setAll(boolean all) { * command line. * * @param amend - * whether to ammend the tip of the current branch + * whether to amend the tip of the current branch * @return {@code this} */ public CommitCommand setAmend(boolean amend) {