diff --git a/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java b/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java
index 3823b2b3a7..881a374864 100644
--- a/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java
+++ b/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandBuilder.java
@@ -10,8 +10,8 @@ import sonia.scm.repository.spi.MergeCommandRequest;
* the branches could be merged without conflicts ({@link #dryRun()}). To do so, you have to specify the name of
* the target branch ({@link #setTargetBranch(String)}) and the name of the branch that should be merged
* ({@link #setBranchToMerge(String)}). Additionally you can specify an author that should be used for the commit
- * ({@link #setAuthor(Person)}) if you are not doing a dry run only. If no author is specified, the logged in user
- * will be used instead.
+ * ({@link #setAuthor(Person)}) and a message template ({@link #setMessageTemplate(String)}) if you are not doing a dry
+ * run only. If no author is specified, the logged in user and a default message will be used instead.
*
* To actually merge feature_branch into integration_branch do this:
*
@@ -91,6 +91,25 @@ public class MergeCommandBuilder {
return this;
}
+ /**
+ * Use this to set a template for the commit message. If no message is set, a default message will be used.
+ *
+ * You can use the placeholder {0} for the branch to be merged and {1} for the target
+ * branch, eg.:
+ *
+ *
+ * ...setMessageTemplate("Merge of {0} into {1}")...
+ *
+ *
+ * This is optional and for {@link #executeMerge()} only.
+ *
+ * @return This builder instance.
+ */
+ public MergeCommandBuilder setMessageTemplate(String messageTemplate) {
+ request.setMessageTemplate(messageTemplate);
+ return this;
+ }
+
/**
* Use this to reset the command.
* @return This builder instance.
diff --git a/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java b/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java
index 05f160ec0a..baf03a0aef 100644
--- a/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java
+++ b/scm-core/src/main/java/sonia/scm/repository/spi/MergeCommandRequest.java
@@ -16,6 +16,7 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl
private String branchToMerge;
private String targetBranch;
private Person author;
+ private String messageTemplate;
public String getBranchToMerge() {
return branchToMerge;
@@ -41,6 +42,14 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl
this.author = author;
}
+ public String getMessageTemplate() {
+ return messageTemplate;
+ }
+
+ public void setMessageTemplate(String messageTemplate) {
+ this.messageTemplate = messageTemplate;
+ }
+
public boolean isValid() {
return !Strings.isNullOrEmpty(getBranchToMerge())
&& !Strings.isNullOrEmpty(getTargetBranch());
diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java
index f61038b069..05541e8295 100644
--- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java
+++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommand.java
@@ -1,5 +1,6 @@
package sonia.scm.repository.spi;
+import com.google.common.base.Strings;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.eclipse.jgit.api.Git;
@@ -19,15 +20,16 @@ import sonia.scm.repository.api.MergeDryRunCommandResult;
import sonia.scm.user.User;
import java.io.IOException;
+import java.text.MessageFormat;
public class GitMergeCommand extends AbstractGitCommand implements MergeCommand {
private static final Logger logger = LoggerFactory.getLogger(GitMergeCommand.class);
- private static final String MERGE_COMMIT_MESSAGE_TEMPLATE =
- "Merge of branch %s into %s\n" +
- "\n" +
- "Automatic merge by SCM-Manager.";
+ private static final String MERGE_COMMIT_MESSAGE_TEMPLATE = String.join("\n",
+ "Merge of branch {0} into {1}",
+ "",
+ "Automatic merge by SCM-Manager.");
private final GitWorkdirFactory workdirFactory;
@@ -64,11 +66,13 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
private final String toMerge;
private final Person author;
private final Git clone;
+ private final String messageTemplate;
private MergeWorker(Repository clone, MergeCommandRequest request) {
this.target = request.getTargetBranch();
this.toMerge = request.getBranchToMerge();
this.author = request.getAuthor();
+ this.messageTemplate = request.getMessageTemplate();
this.clone = new Git(clone);
}
@@ -111,13 +115,21 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
try {
clone.commit()
.setAuthor(authorToUse.getName(), authorToUse.getMail())
- .setMessage(String.format(MERGE_COMMIT_MESSAGE_TEMPLATE, toMerge, target))
+ .setMessage(MessageFormat.format(determineMessageTemplate(), toMerge, target))
.call();
} catch (GitAPIException e) {
throw new InternalRepositoryException("could not commit merge between branch " + toMerge + " and " + target, e);
}
}
+ private String determineMessageTemplate() {
+ if (Strings.isNullOrEmpty(messageTemplate)) {
+ return MERGE_COMMIT_MESSAGE_TEMPLATE;
+ } else {
+ return messageTemplate;
+ }
+ }
+
private Person determineAuthor() {
if (author == null) {
Subject subject = SecurityUtils.getSubject();
diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java
index 5bb9af7d8f..1fca7814ed 100644
--- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java
+++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/spi/GitMergeCommandTest.java
@@ -67,14 +67,36 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
Iterable commits = new Git(repository).log().add(repository.resolve("master")).setMaxCount(1).call();
RevCommit mergeCommit = commits.iterator().next();
PersonIdent mergeAuthor = mergeCommit.getAuthorIdent();
+ String message = mergeCommit.getFullMessage();
assertThat(mergeAuthor.getName()).isEqualTo("Dirk Gently");
assertThat(mergeAuthor.getEmailAddress()).isEqualTo("dirk@holistic.det");
+ assertThat(message).contains("master", "mergeable");
// We expect the merge result of file b.txt here by looking up the sha hash of its content.
// If the file is missing (aka not merged correctly) this will throw a MissingObjectException:
byte[] contentOfFileB = repository.open(repository.resolve("9513e9c76e73f3e562fd8e4c909d0607113c77c6")).getBytes();
assertThat(new String(contentOfFileB)).isEqualTo("b\ncontent from branch\n");
}
+ @Test
+ public void shouldUseConfiguredCommitMessageTemplate() throws IOException, GitAPIException {
+ GitMergeCommand command = createCommand();
+ MergeCommandRequest request = new MergeCommandRequest();
+ request.setTargetBranch("master");
+ request.setBranchToMerge("mergeable");
+ request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
+ request.setMessageTemplate("simple");
+
+ MergeCommandResult mergeCommandResult = command.merge(request);
+
+ assertThat(mergeCommandResult.isSuccess()).isTrue();
+
+ Repository repository = createContext().open();
+ Iterable commits = new Git(repository).log().add(repository.resolve("master")).setMaxCount(1).call();
+ RevCommit mergeCommit = commits.iterator().next();
+ String message = mergeCommit.getFullMessage();
+ assertThat(message).isEqualTo("simple");
+ }
+
@Test
public void shouldNotMergeConflictingBranches() {
GitMergeCommand command = createCommand();