mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-10 15:35:49 +01:00
implement squash to mergeCommand
This commit is contained in:
@@ -92,6 +92,18 @@ public class MergeCommandBuilder {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use this to set the strategy of the merge commit manually.
|
||||||
|
*
|
||||||
|
* This is optional and for {@link #executeMerge()} only.
|
||||||
|
*
|
||||||
|
* @return This builder instance.
|
||||||
|
*/
|
||||||
|
public MergeCommandBuilder setMergeStrategy(ScmMergeStrategy strategy) {
|
||||||
|
request.setScmMergeStrategy(strategy);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use this to set a template for the commit message. If no message is set, a default message will be used.
|
* Use this to set a template for the commit message. If no message is set, a default message will be used.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package sonia.scm.repository.api;
|
||||||
|
|
||||||
|
public enum ScmMergeStrategy {
|
||||||
|
SQUASH
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import com.google.common.base.Objects;
|
|||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
import sonia.scm.Validateable;
|
import sonia.scm.Validateable;
|
||||||
import sonia.scm.repository.Person;
|
import sonia.scm.repository.Person;
|
||||||
|
import sonia.scm.repository.api.ScmMergeStrategy;
|
||||||
import sonia.scm.repository.util.AuthorUtil.CommandWithAuthor;
|
import sonia.scm.repository.util.AuthorUtil.CommandWithAuthor;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
@@ -17,6 +18,7 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl
|
|||||||
private String targetBranch;
|
private String targetBranch;
|
||||||
private Person author;
|
private Person author;
|
||||||
private String messageTemplate;
|
private String messageTemplate;
|
||||||
|
private ScmMergeStrategy scmMergeStrategy;
|
||||||
|
|
||||||
public String getBranchToMerge() {
|
public String getBranchToMerge() {
|
||||||
return branchToMerge;
|
return branchToMerge;
|
||||||
@@ -50,6 +52,14 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl
|
|||||||
this.messageTemplate = messageTemplate;
|
this.messageTemplate = messageTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ScmMergeStrategy getScmMergeStrategy() {
|
||||||
|
return scmMergeStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setScmMergeStrategy(ScmMergeStrategy scmMergeStrategy) {
|
||||||
|
this.scmMergeStrategy = scmMergeStrategy;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isValid() {
|
public boolean isValid() {
|
||||||
return !Strings.isNullOrEmpty(getBranchToMerge())
|
return !Strings.isNullOrEmpty(getBranchToMerge())
|
||||||
&& !Strings.isNullOrEmpty(getTargetBranch());
|
&& !Strings.isNullOrEmpty(getTargetBranch());
|
||||||
@@ -74,12 +84,13 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl
|
|||||||
|
|
||||||
return Objects.equal(branchToMerge, other.branchToMerge)
|
return Objects.equal(branchToMerge, other.branchToMerge)
|
||||||
&& Objects.equal(targetBranch, other.targetBranch)
|
&& Objects.equal(targetBranch, other.targetBranch)
|
||||||
&& Objects.equal(author, other.author);
|
&& Objects.equal(author, other.author)
|
||||||
|
&& Objects.equal(scmMergeStrategy, other.scmMergeStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hashCode(branchToMerge, targetBranch, author);
|
return Objects.hashCode(branchToMerge, targetBranch, author, scmMergeStrategy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -88,6 +99,7 @@ public class MergeCommandRequest implements Validateable, Resetable, Serializabl
|
|||||||
.add("branchToMerge", branchToMerge)
|
.add("branchToMerge", branchToMerge)
|
||||||
.add("targetBranch", targetBranch)
|
.add("targetBranch", targetBranch)
|
||||||
.add("author", author)
|
.add("author", author)
|
||||||
|
.add("mergeStrategy", scmMergeStrategy)
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import sonia.scm.repository.InternalRepositoryException;
|
|||||||
import sonia.scm.repository.Person;
|
import sonia.scm.repository.Person;
|
||||||
import sonia.scm.repository.api.MergeCommandResult;
|
import sonia.scm.repository.api.MergeCommandResult;
|
||||||
import sonia.scm.repository.api.MergeDryRunCommandResult;
|
import sonia.scm.repository.api.MergeDryRunCommandResult;
|
||||||
|
import sonia.scm.repository.api.ScmMergeStrategy;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.MessageFormat;
|
import java.text.MessageFormat;
|
||||||
@@ -61,6 +62,7 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
|
|||||||
private final String toMerge;
|
private final String toMerge;
|
||||||
private final Person author;
|
private final Person author;
|
||||||
private final String messageTemplate;
|
private final String messageTemplate;
|
||||||
|
private final ScmMergeStrategy scmMergeStrategy;
|
||||||
|
|
||||||
private MergeWorker(Git clone, MergeCommandRequest request) {
|
private MergeWorker(Git clone, MergeCommandRequest request) {
|
||||||
super(clone);
|
super(clone);
|
||||||
@@ -68,6 +70,7 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
|
|||||||
this.toMerge = request.getBranchToMerge();
|
this.toMerge = request.getBranchToMerge();
|
||||||
this.author = request.getAuthor();
|
this.author = request.getAuthor();
|
||||||
this.messageTemplate = request.getMessageTemplate();
|
this.messageTemplate = request.getMessageTemplate();
|
||||||
|
this.scmMergeStrategy = request.getScmMergeStrategy();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -86,11 +89,18 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
|
|||||||
MergeResult result;
|
MergeResult result;
|
||||||
try {
|
try {
|
||||||
ObjectId sourceRevision = resolveRevision(toMerge);
|
ObjectId sourceRevision = resolveRevision(toMerge);
|
||||||
result = getClone().merge()
|
org.eclipse.jgit.api.MergeCommand mergeCommand = getClone().merge();
|
||||||
.setFastForward(FastForwardMode.NO_FF)
|
mergeCommand
|
||||||
.setCommit(false) // we want to set the author manually
|
.setCommit(false) // we want to set the author manually
|
||||||
.include(toMerge, sourceRevision)
|
.include(toMerge, sourceRevision);
|
||||||
.call();
|
|
||||||
|
if (scmMergeStrategy == ScmMergeStrategy.SQUASH) {
|
||||||
|
mergeCommand.setSquash(true);
|
||||||
|
} else {
|
||||||
|
mergeCommand.setFastForward(FastForwardMode.NO_FF);
|
||||||
|
}
|
||||||
|
|
||||||
|
result = mergeCommand.call();
|
||||||
} catch (GitAPIException e) {
|
} catch (GitAPIException e) {
|
||||||
throw new InternalRepositoryException(context.getRepository(), "could not merge branch " + toMerge + " into " + target, e);
|
throw new InternalRepositoryException(context.getRepository(), "could not merge branch " + toMerge + " into " + target, e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,12 @@ import org.junit.Test;
|
|||||||
import sonia.scm.NotFoundException;
|
import sonia.scm.NotFoundException;
|
||||||
import sonia.scm.repository.Person;
|
import sonia.scm.repository.Person;
|
||||||
import sonia.scm.repository.api.MergeCommandResult;
|
import sonia.scm.repository.api.MergeCommandResult;
|
||||||
|
import sonia.scm.repository.api.ScmMergeStrategy;
|
||||||
import sonia.scm.repository.util.WorkdirProvider;
|
import sonia.scm.repository.util.WorkdirProvider;
|
||||||
import sonia.scm.user.User;
|
import sonia.scm.user.User;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
@@ -211,6 +213,55 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
|
|||||||
assertThat(new String(contentOfFileB)).isEqualTo("b\ncontent from branch\n");
|
assertThat(new String(contentOfFileB)).isEqualTo("b\ncontent from branch\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSquashCommitsIfSquashIsEnabled() throws IOException, GitAPIException {
|
||||||
|
GitMergeCommand command = createCommand();
|
||||||
|
MergeCommandRequest request = new MergeCommandRequest();
|
||||||
|
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
|
||||||
|
request.setBranchToMerge("squash");
|
||||||
|
request.setTargetBranch("master");
|
||||||
|
request.setMessageTemplate("this is a squash");
|
||||||
|
request.setScmMergeStrategy(ScmMergeStrategy.SQUASH);
|
||||||
|
|
||||||
|
MergeCommandResult mergeCommandResult = command.merge(request);
|
||||||
|
|
||||||
|
Repository repository = createContext().open();
|
||||||
|
assertThat(mergeCommandResult.isSuccess()).isTrue();
|
||||||
|
|
||||||
|
Iterable<RevCommit> 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(message).isEqualTo("this is a squash");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void shouldSquashThreeCommitsIntoOne() throws IOException, GitAPIException {
|
||||||
|
GitMergeCommand command = createCommand();
|
||||||
|
MergeCommandRequest request = new MergeCommandRequest();
|
||||||
|
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
|
||||||
|
request.setBranchToMerge("squash");
|
||||||
|
request.setTargetBranch("master");
|
||||||
|
request.setMessageTemplate("squash three commits");
|
||||||
|
request.setScmMergeStrategy(ScmMergeStrategy.SQUASH);
|
||||||
|
Repository gitRepository = createContext().open();
|
||||||
|
MergeCommandResult mergeCommandResult = command.merge(request);
|
||||||
|
|
||||||
|
assertThat(mergeCommandResult.isSuccess()).isTrue();
|
||||||
|
|
||||||
|
Iterable<RevCommit> commits = new Git(gitRepository).log().add(gitRepository.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(message).isEqualTo("squash three commits");
|
||||||
|
|
||||||
|
GitModificationsCommand modificationsCommand = new GitModificationsCommand(createContext(), repository);
|
||||||
|
List<String> changes = modificationsCommand.getModifications("master").getAdded();
|
||||||
|
assertThat(changes.size()).isEqualTo(3);
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = NotFoundException.class)
|
@Test(expected = NotFoundException.class)
|
||||||
public void shouldHandleNotExistingSourceBranchInMerge() {
|
public void shouldHandleNotExistingSourceBranchInMerge() {
|
||||||
GitMergeCommand command = createCommand();
|
GitMergeCommand command = createCommand();
|
||||||
|
|||||||
Binary file not shown.
Reference in New Issue
Block a user