diff --git a/scm-core/pom.xml b/scm-core/pom.xml
index c7bbc664c9..8437b256b2 100644
--- a/scm-core/pom.xml
+++ b/scm-core/pom.xml
@@ -214,6 +214,12 @@
shiro-unit
test
+
+ org.hibernate
+ hibernate-validator
+ 5.3.6.Final
+ compile
+
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MergeCommandDto.java b/scm-core/src/main/java/sonia/scm/api/v2/resources/MergeCommandDto.java
similarity index 100%
rename from scm-webapp/src/main/java/sonia/scm/api/v2/resources/MergeCommandDto.java
rename to scm-core/src/main/java/sonia/scm/api/v2/resources/MergeCommandDto.java
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 d3c78ae9da..d7e8482f55 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
@@ -64,6 +64,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
MergeCommandRequest request = new MergeCommandRequest();
request.setTargetBranch("master");
request.setBranchToMerge("mergeable");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
MergeCommandResult mergeCommandResult = command.merge(request);
@@ -90,6 +91,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
MergeCommandRequest request = new MergeCommandRequest();
request.setTargetBranch("master");
request.setBranchToMerge("empty_merge");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
MergeCommandResult mergeCommandResult = command.merge(request);
@@ -111,6 +113,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
request.setTargetBranch("master");
request.setBranchToMerge("mergeable");
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
MergeCommandResult mergeCommandResult = command.merge(request);
@@ -134,6 +137,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
MergeCommandRequest request = new MergeCommandRequest();
request.setTargetBranch("master");
request.setBranchToMerge("mergeable");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
request.setMessageTemplate("simple");
@@ -154,6 +158,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
MergeCommandRequest request = new MergeCommandRequest();
request.setBranchToMerge("test-branch");
request.setTargetBranch("master");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
MergeCommandResult mergeCommandResult = command.merge(request);
@@ -175,6 +180,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
MergeCommandRequest request = new MergeCommandRequest();
request.setTargetBranch("master");
request.setBranchToMerge("mergeable");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
MergeCommandResult mergeCommandResult = command.merge(request);
@@ -194,6 +200,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
request.setTargetBranch("mergeable");
request.setBranchToMerge("master");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
MergeCommandResult mergeCommandResult = command.merge(request);
@@ -316,6 +323,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
MergeCommandRequest request = new MergeCommandRequest();
request.setTargetBranch("mergeable");
request.setBranchToMerge("not_existing");
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
command.merge(request);
}
@@ -324,6 +332,7 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
public void shouldHandleNotExistingTargetBranchInMerge() {
GitMergeCommand command = createCommand();
MergeCommandRequest request = new MergeCommandRequest();
+ request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
request.setTargetBranch("not_existing");
request.setBranchToMerge("master");
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MergeResource.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MergeResource.java
deleted file mode 100644
index df59ba2abc..0000000000
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/MergeResource.java
+++ /dev/null
@@ -1,95 +0,0 @@
-package sonia.scm.api.v2.resources;
-
-import com.webcohesion.enunciate.metadata.rs.ResponseCode;
-import com.webcohesion.enunciate.metadata.rs.StatusCodes;
-import lombok.extern.slf4j.Slf4j;
-import org.apache.http.HttpStatus;
-import sonia.scm.ConcurrentModificationException;
-import sonia.scm.repository.NamespaceAndName;
-import sonia.scm.repository.RepositoryPermissions;
-import sonia.scm.repository.api.MergeCommandBuilder;
-import sonia.scm.repository.api.MergeCommandResult;
-import sonia.scm.repository.api.MergeDryRunCommandResult;
-import sonia.scm.repository.api.RepositoryService;
-import sonia.scm.repository.api.RepositoryServiceFactory;
-import sonia.scm.web.VndMediaType;
-
-import javax.inject.Inject;
-import javax.validation.Valid;
-import javax.ws.rs.Consumes;
-import javax.ws.rs.POST;
-import javax.ws.rs.Path;
-import javax.ws.rs.PathParam;
-import javax.ws.rs.Produces;
-import javax.ws.rs.core.Response;
-
-@Slf4j
-public class MergeResource {
-
- private final RepositoryServiceFactory serviceFactory;
- private final MergeResultToDtoMapper mapper;
-
- @Inject
- public MergeResource(RepositoryServiceFactory serviceFactory, MergeResultToDtoMapper mapper) {
- this.serviceFactory = serviceFactory;
- this.mapper = mapper;
- }
-
- @POST
- @Path("")
- @Produces(VndMediaType.MERGE_RESULT)
- @Consumes(VndMediaType.MERGE_COMMAND)
- @StatusCodes({
- @ResponseCode(code = 204, condition = "merge has been executed successfully"),
- @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
- @ResponseCode(code = 403, condition = "not authorized, the current user does not have the privilege to write the repository"),
- @ResponseCode(code = 409, condition = "The branches could not be merged automatically due to conflicts (conflicting files will be returned)"),
- @ResponseCode(code = 500, condition = "internal server error")
- })
- public Response merge(@PathParam("namespace") String namespace, @PathParam("name") String name, @Valid MergeCommandDto mergeCommand) {
- NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name);
- log.info("Merge in Repository {}/{} from {} to {}", namespace, name, mergeCommand.getSourceRevision(), mergeCommand.getTargetRevision());
- try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
- RepositoryPermissions.push(repositoryService.getRepository()).check();
- MergeCommandResult mergeCommandResult = createMergeCommand(mergeCommand, repositoryService).executeMerge();
- if (mergeCommandResult.isSuccess()) {
- return Response.noContent().build();
- } else {
- return Response.status(HttpStatus.SC_CONFLICT).entity(mapper.map(mergeCommandResult)).build();
- }
- }
- }
-
- @POST
- @Path("dry-run/")
- @StatusCodes({
- @ResponseCode(code = 204, condition = "merge can be done automatically"),
- @ResponseCode(code = 401, condition = "not authenticated / invalid credentials"),
- @ResponseCode(code = 409, condition = "The branches can not be merged automatically due to conflicts"),
- @ResponseCode(code = 500, condition = "internal server error")
- })
- public Response dryRun(@PathParam("namespace") String namespace, @PathParam("name") String name, @Valid MergeCommandDto mergeCommand) {
-
- NamespaceAndName namespaceAndName = new NamespaceAndName(namespace, name);
- log.info("Merge in Repository {}/{} from {} to {}", namespace, name, mergeCommand.getSourceRevision(), mergeCommand.getTargetRevision());
- try (RepositoryService repositoryService = serviceFactory.create(namespaceAndName)) {
- if (RepositoryPermissions.push(repositoryService.getRepository()).isPermitted()) {
- MergeDryRunCommandResult mergeCommandResult = createMergeCommand(mergeCommand, repositoryService).dryRun();
- if (mergeCommandResult.isMergeable()) {
- return Response.noContent().build();
- } else {
- throw new ConcurrentModificationException("revision", mergeCommand.getTargetRevision());
- }
- } else {
- return Response.noContent().build();
- }
- }
- }
-
- private MergeCommandBuilder createMergeCommand(MergeCommandDto mergeCommand, RepositoryService repositoryService) {
- return repositoryService
- .getMergeCommand()
- .setBranchToMerge(mergeCommand.getSourceRevision())
- .setTargetBranch(mergeCommand.getTargetRevision());
- }
-}
diff --git a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
index 67a6f26de5..c09f90c83d 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/v2/resources/RepositoryToRepositoryDtoMapper.java
@@ -63,12 +63,6 @@ public abstract class RepositoryToRepositoryDtoMapper extends BaseMapper