diff --git a/scm-it/pom.xml b/scm-it/pom.xml
index 90c22cda75..cdfd14f3e3 100644
--- a/scm-it/pom.xml
+++ b/scm-it/pom.xml
@@ -192,6 +192,7 @@
2.10
+
sonia.scm
scm-webapp
@@ -200,6 +201,15 @@
${project.build.outputDirectory}
scm-webapp.war
+
+
+ sonia.scm.plugins
+ scm-integration-test-plugin
+ ${project.version}
+ smp
+ ${scm.home}/plugins
+ scm-integration-test-plugin.smp
+
diff --git a/scm-it/src/test/java/sonia/scm/it/MergeDetectionITCase.java b/scm-it/src/test/java/sonia/scm/it/MergeDetectionITCase.java
new file mode 100644
index 0000000000..6779b76b68
--- /dev/null
+++ b/scm-it/src/test/java/sonia/scm/it/MergeDetectionITCase.java
@@ -0,0 +1,176 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.it;
+
+import io.restassured.RestAssured;
+import org.assertj.core.api.Assertions;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import sonia.scm.it.utils.RepositoryUtil;
+import sonia.scm.it.utils.RestUtil;
+import sonia.scm.it.utils.TestData;
+import sonia.scm.repository.Person;
+import sonia.scm.repository.client.api.RepositoryClient;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+
+import static java.lang.String.format;
+import static java.util.Collections.singletonList;
+import static sonia.scm.it.utils.TestData.USER_SCM_ADMIN;
+
+public class MergeDetectionITCase {
+
+ private static final Person ARTHUR = new Person("arthur", "arthur@hitchhiker.com");
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ RepositoryClient client;
+ String masterFile;
+ String developFile;
+
+ @Before
+ public void createRepository() throws IOException {
+ TestData.createDefault();
+
+ client = RepositoryUtil.createRepositoryClient("git", temporaryFolder.getRoot());
+
+ masterFile = createFile("hg2g.md");
+ developFile = createFile("how_to_make_tea.md");
+
+ client.getAddCommand().add(masterFile);
+ client.getCommitCommand().commit(ARTHUR, "Add base file");
+ client.getPushCommand().push();
+
+ client.getBranchCommand().branch("develop");
+ client.getCheckoutCommand().checkout("develop");
+ client.getAddCommand().add(developFile);
+ client.getCommitCommand().commit(ARTHUR, "add more important things");
+ client.getPushCommand().push();
+ }
+
+ @After
+ public void disableMergeDetection() {
+ RestAssured.given()
+ .auth().preemptive().basic(USER_SCM_ADMIN, USER_SCM_ADMIN)
+ .when()
+ .contentType("application/json")
+ .accept("application/json")
+ .body(toJson("{}"))
+ .post(RestUtil.createResourceUrl("integration-test/merge-detection/"))
+ .then()
+ .statusCode(204);
+ }
+
+ @Test
+ public void shouldDetectSimpleMergeAsMerged() throws IOException {
+ client.getCheckoutCommand().checkout("master");
+ client.getMergeCommand().merge("develop");
+
+ initializeMergeDetection("master", "develop");
+
+ client.getPushCommand().push();
+
+ Assertions.assertThat(getMergeDetectionResult("preMergeDetection", 0)).isTrue();
+ Assertions.assertThat(getMergeDetectionResult("postMergeDetection", 0)).isTrue();
+ }
+
+ @Test
+ public void shouldDetectMergeWhenBranchHasBeenDeletedAsMerged() throws IOException {
+ client.getCheckoutCommand().checkout("master");
+ client.getMergeCommand().merge("develop");
+ client.getPushCommand().push();
+
+ initializeMergeDetection("master", "develop");
+
+ client.getDeleteRemoteBranchCommand().delete("develop");
+ client.getPushCommand().push();
+
+ Assertions.assertThat(getMergeDetectionResult("preMergeDetection", 0)).isTrue();
+ Assertions.assertThat(getMergeDetectionResult("postMergeDetection", 0)).isTrue();
+ }
+
+ @Test
+ public void shouldDetectNormalPushAsNotMerged() throws IOException {
+ client.getCheckoutCommand().checkout("develop");
+ writeFile(developFile, "other content");
+ client.getAddCommand().add(developFile);
+ client.getCommitCommand().commit(ARTHUR, "simple commit");
+
+ initializeMergeDetection("master", "develop");
+
+ client.getPushCommand().push();
+
+ Assertions.assertThat(getMergeDetectionResult("preMergeDetection", 0)).isFalse();
+ Assertions.assertThat(getMergeDetectionResult("postMergeDetection", 0)).isFalse();
+ }
+
+ private boolean getMergeDetectionResult(String type, int n) {
+ return RestAssured.given()
+ .auth().preemptive().basic(USER_SCM_ADMIN, USER_SCM_ADMIN)
+ .when()
+ .accept("application/json")
+ .get(RestUtil.createResourceUrl("integration-test/"))
+ .then()
+ .statusCode(200)
+ .extract()
+ .jsonPath()
+ .getBoolean("_embedded." +
+ type +
+ "[" + n + "].merged");
+ }
+
+ private void initializeMergeDetection(String target, String branch) {
+ RestAssured.given()
+ .auth().preemptive().basic(USER_SCM_ADMIN, USER_SCM_ADMIN)
+ .when()
+ .contentType("application/json")
+ .accept("application/json")
+ .body(toJson(format("{'target': '%s', 'branch': '%s'}", target, branch)))
+ .post(RestUtil.createResourceUrl("integration-test/merge-detection/"))
+ .then()
+ .statusCode(204);
+ }
+
+ private String createFile(String name) throws IOException {
+ temporaryFolder.newFile(name);
+ writeFile(name, "Some content");
+ return name;
+ }
+
+ private void writeFile(String name, String content) throws IOException {
+ Path file = temporaryFolder.getRoot().toPath().resolve(name);
+ Files.write(file, singletonList(content));
+ }
+
+ private String toJson(String json) {
+ return json.replaceAll("'", "\"");
+ }
+}
diff --git a/scm-plugins/pom.xml b/scm-plugins/pom.xml
index a407c38471..f4f927fe0e 100644
--- a/scm-plugins/pom.xml
+++ b/scm-plugins/pom.xml
@@ -45,6 +45,7 @@
scm-git-plugin
scm-svn-plugin
scm-legacy-plugin
+ scm-integration-test-plugin
diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitCheckoutCommand.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitCheckoutCommand.java
new file mode 100644
index 0000000000..1db0140041
--- /dev/null
+++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitCheckoutCommand.java
@@ -0,0 +1,49 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import sonia.scm.repository.client.api.RepositoryClientException;
+
+import java.io.IOException;
+
+public class GitCheckoutCommand implements CheckoutCommand {
+
+ private Git git;
+
+ GitCheckoutCommand(Git git) {
+ this.git = git;
+ }
+
+ @Override
+ public void checkout(String name) throws IOException {
+ try {
+ git.checkout().setName(name).call();
+ } catch (GitAPIException ex) {
+ throw new RepositoryClientException("could not checkout branch or revision", ex);
+ }
+ }
+}
diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitDeleteRemoteBranchCommand.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitDeleteRemoteBranchCommand.java
new file mode 100644
index 0000000000..e7a5b03c25
--- /dev/null
+++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitDeleteRemoteBranchCommand.java
@@ -0,0 +1,64 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.PushCommand;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.transport.CredentialsProvider;
+import org.eclipse.jgit.transport.RefSpec;
+import sonia.scm.repository.client.api.RepositoryClientException;
+
+import java.io.IOException;
+
+public class GitDeleteRemoteBranchCommand implements DeleteRemoteBranchCommand {
+
+ private final Git git;
+ private final CredentialsProvider credentialsProvider;
+
+ GitDeleteRemoteBranchCommand(Git git, CredentialsProvider credentialsProvider) {
+ this.git = git;
+ this.credentialsProvider = credentialsProvider;
+ }
+
+ @Override
+ public void delete(String name) throws IOException {
+ try {
+ git.branchDelete().setBranchNames("refs/heads/" + name).call();
+ RefSpec refSpec = new RefSpec()
+ .setSource(null)
+ .setDestination("refs/heads/" + name);
+ PushCommand push = git.push();
+ if (credentialsProvider != null) {
+ push.setCredentialsProvider(credentialsProvider);
+ }
+ push.setRefSpecs(refSpec).call();
+
+// List result = git.branchDelete().setBranchNames(name).call();
+ } catch (GitAPIException ex) {
+ throw new RepositoryClientException("could not delete branch", ex);
+ }
+ }
+}
diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitMergeCommand.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitMergeCommand.java
new file mode 100644
index 0000000000..6b27ee4a06
--- /dev/null
+++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitMergeCommand.java
@@ -0,0 +1,64 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.api.MergeResult;
+import org.eclipse.jgit.api.errors.GitAPIException;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.revwalk.RevCommit;
+import org.eclipse.jgit.revwalk.RevWalk;
+import sonia.scm.repository.Changeset;
+import sonia.scm.repository.GitChangesetConverter;
+import sonia.scm.repository.client.api.RepositoryClientException;
+
+import java.io.IOException;
+
+public class GitMergeCommand implements MergeCommand {
+
+ private final Git git;
+
+ GitMergeCommand(Git git) {
+ this.git = git;
+ }
+
+ @Override
+ public Changeset merge(MergeRequest request) throws IOException {
+ try (GitChangesetConverter converter = new GitChangesetConverter(git.getRepository())) {
+ ObjectId resolved = git.getRepository().resolve(request.getBranch());
+ MergeResult mergeResult = git.merge()
+ .include(request.getBranch(), resolved)
+ .setMessage(request.getMessage())
+ .call();
+
+ try (RevWalk revWalk = new RevWalk(git.getRepository())) {
+ RevCommit commit = revWalk.parseCommit(mergeResult.getNewHead());
+ return converter.createChangeset(commit);
+ }
+ } catch (GitAPIException ex) {
+ throw new RepositoryClientException("could not commit changes to repository", ex);
+ }
+ }
+}
diff --git a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitRepositoryClientProvider.java b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitRepositoryClientProvider.java
index 665e4bc8eb..1cb11dbe2c 100644
--- a/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitRepositoryClientProvider.java
+++ b/scm-plugins/scm-git-plugin/src/test/java/sonia/scm/repository/client/spi/GitRepositoryClientProvider.java
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
+
package sonia.scm.repository.client.spi;
//~--- non-JDK imports --------------------------------------------------------
@@ -49,7 +49,7 @@ public class GitRepositoryClientProvider extends RepositoryClientProvider
private static final Set SUPPORTED_COMMANDS =
ImmutableSet.of(ClientCommand.ADD, ClientCommand.REMOVE,
ClientCommand.COMMIT, ClientCommand.TAG, ClientCommand.BRANCH,
- ClientCommand.PUSH);
+ ClientCommand.DELETE_REMOTE_BRANCH, ClientCommand.MERGE, ClientCommand.PUSH);
//~--- constructors ---------------------------------------------------------
@@ -118,6 +118,16 @@ public class GitRepositoryClientProvider extends RepositoryClientProvider
return new GitBranchCommand(git);
}
+ @Override
+ public DeleteRemoteBranchCommand getDeleteRemoteBranchCommand() {
+ return new GitDeleteRemoteBranchCommand(git, credentialsProvider);
+ }
+
+ @Override
+ public CheckoutCommand getCheckoutCommand() {
+ return new GitCheckoutCommand(git);
+ }
+
/**
* Method description
*
@@ -178,6 +188,11 @@ public class GitRepositoryClientProvider extends RepositoryClientProvider
return new GitTagCommand(git);
}
+ @Override
+ public MergeCommand getMergeCommand() {
+ return new GitMergeCommand(git);
+ }
+
@Override
public File getWorkingCopy() {
return git.getRepository().getWorkTree();
diff --git a/scm-plugins/scm-integration-test-plugin/pom.xml b/scm-plugins/scm-integration-test-plugin/pom.xml
new file mode 100644
index 0000000000..4728510608
--- /dev/null
+++ b/scm-plugins/scm-integration-test-plugin/pom.xml
@@ -0,0 +1,52 @@
+
+
+
+ 4.0.0
+
+ sonia.scm.plugins
+ scm-plugins
+ 2.4.0-SNAPSHOT
+
+
+ scm-integration-test-plugin
+ Add functions for integration tests. This is not intended for production systems.
+ 2.4.0-SNAPSHOT
+ smp
+
+
+
+
+
+
+ javax.servlet
+ javax.servlet-api
+ ${servlet.version}
+ provided
+
+
+
+
diff --git a/scm-plugins/scm-integration-test-plugin/src/main/java/sonia/scm/it/resource/IntegrationTestResource.java b/scm-plugins/scm-integration-test-plugin/src/main/java/sonia/scm/it/resource/IntegrationTestResource.java
new file mode 100644
index 0000000000..3d6e131ebd
--- /dev/null
+++ b/scm-plugins/scm-integration-test-plugin/src/main/java/sonia/scm/it/resource/IntegrationTestResource.java
@@ -0,0 +1,113 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.it.resource;
+
+import de.otto.edison.hal.Embedded;
+import de.otto.edison.hal.HalRepresentation;
+import de.otto.edison.hal.Links;
+import io.swagger.v3.oas.annotations.OpenAPIDefinition;
+import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.Getter;
+import lombok.Setter;
+import sonia.scm.api.v2.resources.LinkBuilder;
+import sonia.scm.api.v2.resources.ScmPathInfoStore;
+import sonia.scm.plugin.Extension;
+
+import javax.inject.Inject;
+import javax.ws.rs.Consumes;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+
+import static de.otto.edison.hal.Embedded.embeddedBuilder;
+import static de.otto.edison.hal.Links.linkingTo;
+
+/**
+ * Web Service Resource to support integration tests.
+ */
+@OpenAPIDefinition(tags = {
+ @Tag(name = "Integration Test", description = "Support for integration tests")
+})
+@Path(IntegrationTestResource.INTEGRATION_TEST_PATH_V2)
+@Extension
+public class IntegrationTestResource {
+
+ static final String INTEGRATION_TEST_PATH_V2 = "v2/integration-test";
+
+ private final ScmPathInfoStore scmPathInfoStore;
+ private final MergeDetectionHelper mergeDetectionHelper;
+
+ @Inject
+ public IntegrationTestResource(ScmPathInfoStore scmPathInfoStore, MergeDetectionHelper mergeDetectionHelper) {
+ this.scmPathInfoStore = scmPathInfoStore;
+ this.mergeDetectionHelper = mergeDetectionHelper;
+ }
+
+ @GET
+ @Path("")
+ @Produces("application/json")
+ public CollectionDto get() {
+ Links links = linkingTo()
+ .self(self())
+ .build();
+ Embedded embedded = embeddedBuilder()
+ .with("preMergeDetection", mergeDetectionHelper.getPreMergeDetections())
+ .with("postMergeDetection", mergeDetectionHelper.getPostMergeDetections())
+ .build();
+ return new CollectionDto(links, embedded);
+ }
+
+ @POST
+ @Path("merge-detection")
+ @Consumes("application/json")
+ public void initMergeDetection(MergeDetectionConfigurationDto mergeDetectionConfiguration) {
+ mergeDetectionHelper.initialize(mergeDetectionConfiguration.getTarget(), mergeDetectionConfiguration.getBranch());
+ }
+
+ private String self() {
+ LinkBuilder linkBuilder = new LinkBuilder(scmPathInfoStore.get(), IntegrationTestResource.class);
+ return linkBuilder.method("get").parameters().href();
+ }
+
+ static class CollectionDto extends HalRepresentation {
+
+ CollectionDto(Links links, Embedded embedded) {
+ super(links, embedded);
+ }
+
+ @Override
+ protected HalRepresentation withEmbedded(String rel, HalRepresentation embeddedItem) {
+ return super.withEmbedded(rel, embeddedItem);
+ }
+ }
+
+ @Getter
+ @Setter
+ static class MergeDetectionConfigurationDto {
+ private String target;
+ private String branch;
+ }
+}
diff --git a/scm-plugins/scm-integration-test-plugin/src/main/java/sonia/scm/it/resource/MergeDetectionHelper.java b/scm-plugins/scm-integration-test-plugin/src/main/java/sonia/scm/it/resource/MergeDetectionHelper.java
new file mode 100644
index 0000000000..10d9fbc31a
--- /dev/null
+++ b/scm-plugins/scm-integration-test-plugin/src/main/java/sonia/scm/it/resource/MergeDetectionHelper.java
@@ -0,0 +1,101 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.it.resource;
+
+import com.github.legman.Subscribe;
+import de.otto.edison.hal.HalRepresentation;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import sonia.scm.EagerSingleton;
+import sonia.scm.plugin.Extension;
+import sonia.scm.repository.PostReceiveRepositoryHookEvent;
+import sonia.scm.repository.PreReceiveRepositoryHookEvent;
+import sonia.scm.repository.RepositoryHookEvent;
+import sonia.scm.repository.spi.HookMergeDetectionProvider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+@EagerSingleton
+@Extension
+public class MergeDetectionHelper {
+
+ private final List preMergeDetections = new ArrayList<>();
+ private final List postMergeDetections = new ArrayList<>();
+
+ private String target;
+ private String branch;
+
+ @Subscribe
+ public void handlePreReceiveEvent(PreReceiveRepositoryHookEvent event) {
+ if (target == null || branch == null) {
+ return;
+ }
+ preMergeDetections.add(createDto(event));
+ }
+
+ @Subscribe
+ public void handlePostReceiveEvent(PostReceiveRepositoryHookEvent event) {
+ if (target == null || branch == null) {
+ return;
+ }
+ postMergeDetections.add(createDto(event));
+ }
+
+ public ResultDto createDto(RepositoryHookEvent event) {
+ HookMergeDetectionProvider mergeDetectionProvider = event.getContext().getMergeDetectionProvider();
+ boolean merged = mergeDetectionProvider.branchesMerged(target, branch);
+ return new ResultDto(
+ event.getClass().getSimpleName(),
+ event.getRepository().getNamespace(),
+ event.getRepository().getName(),
+ merged
+ );
+ }
+
+ void initialize(String target, String branch) {
+ this.target = target;
+ this.branch = branch;
+ preMergeDetections.clear();
+ postMergeDetections.clear();
+ }
+
+ public List getPreMergeDetections() {
+ return preMergeDetections;
+ }
+
+ public List getPostMergeDetections() {
+ return postMergeDetections;
+ }
+
+ @Getter
+ @AllArgsConstructor
+ static class ResultDto extends HalRepresentation {
+ private String type;
+ private String namespace;
+ private String name;
+ private boolean merged;
+ }
+}
diff --git a/scm-plugins/scm-integration-test-plugin/src/main/resources/META-INF/scm/plugin.xml b/scm-plugins/scm-integration-test-plugin/src/main/resources/META-INF/scm/plugin.xml
new file mode 100644
index 0000000000..f2f70ba9ff
--- /dev/null
+++ b/scm-plugins/scm-integration-test-plugin/src/main/resources/META-INF/scm/plugin.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+ 2
+
+
+ Integration Test Support
+ Cloudogu GmbH
+ Test
+
+
+
+ ${project.parent.version}
+
+
+
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/api/CheckoutCommandBuilder.java b/scm-test/src/main/java/sonia/scm/repository/client/api/CheckoutCommandBuilder.java
new file mode 100644
index 0000000000..9fab6f40c9
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/api/CheckoutCommandBuilder.java
@@ -0,0 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.api;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sonia.scm.repository.client.spi.CheckoutCommand;
+
+import java.io.IOException;
+
+/**
+ * @since 2.4.0
+ */
+public final class CheckoutCommandBuilder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(CheckoutCommandBuilder.class);
+
+ private final CheckoutCommand command;
+
+ public CheckoutCommandBuilder(CheckoutCommand command) {
+ this.command = command;
+ }
+
+ public CheckoutCommandBuilder checkout(String name) throws IOException {
+ LOG.debug("checkout {}", name);
+
+ command.checkout(name);
+
+ return this;
+ }
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/api/ClientCommand.java b/scm-test/src/main/java/sonia/scm/repository/client/api/ClientCommand.java
index bc022a284e..37e1cce24a 100644
--- a/scm-test/src/main/java/sonia/scm/repository/client/api/ClientCommand.java
+++ b/scm-test/src/main/java/sonia/scm/repository/client/api/ClientCommand.java
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
+
package sonia.scm.repository.client.api;
/**
@@ -31,5 +31,5 @@ package sonia.scm.repository.client.api;
*/
public enum ClientCommand
{
- ADD, REMOVE, COMMIT, PUSH, TAG, BRANCH
+ ADD, REMOVE, COMMIT, PUSH, TAG, BRANCH, DELETE_REMOTE_BRANCH, CHECKOUT, MERGE
}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/api/DeleteRemoteBranchCommandBuilder.java b/scm-test/src/main/java/sonia/scm/repository/client/api/DeleteRemoteBranchCommandBuilder.java
new file mode 100644
index 0000000000..cc20321b15
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/api/DeleteRemoteBranchCommandBuilder.java
@@ -0,0 +1,53 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.api;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sonia.scm.repository.client.spi.DeleteRemoteBranchCommand;
+
+import java.io.IOException;
+
+/**
+ * @since 2.4.0
+ */
+public final class DeleteRemoteBranchCommandBuilder {
+
+ private static final Logger LOG = LoggerFactory.getLogger(DeleteRemoteBranchCommandBuilder.class);
+
+ private DeleteRemoteBranchCommand command;
+
+ public DeleteRemoteBranchCommandBuilder(DeleteRemoteBranchCommand command) {
+ this.command = command;
+ }
+
+ public DeleteRemoteBranchCommandBuilder delete(String name) throws IOException {
+ LOG.debug("delete branch {}", name);
+
+ command.delete(name);
+
+ return this;
+ }
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/api/MergeCommandBuilder.java b/scm-test/src/main/java/sonia/scm/repository/client/api/MergeCommandBuilder.java
new file mode 100644
index 0000000000..78cbe240d1
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/api/MergeCommandBuilder.java
@@ -0,0 +1,48 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.api;
+
+import sonia.scm.repository.client.spi.MergeCommand;
+import sonia.scm.repository.client.spi.MergeRequest;
+
+import java.io.IOException;
+
+/**
+ * @since 2.4.0
+ */
+public final class MergeCommandBuilder {
+
+ private final MergeCommand command;
+
+ MergeCommandBuilder(MergeCommand command) {
+ this.command = command;
+ }
+
+ public void merge(String branch) throws IOException {
+ MergeRequest request = new MergeRequest();
+ request.setBranch(branch);
+ command.merge(request);
+ }
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/api/RepositoryClient.java b/scm-test/src/main/java/sonia/scm/repository/client/api/RepositoryClient.java
index 2dbb01d667..660cdb160b 100644
--- a/scm-test/src/main/java/sonia/scm/repository/client/api/RepositoryClient.java
+++ b/scm-test/src/main/java/sonia/scm/repository/client/api/RepositoryClient.java
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
+
package sonia.scm.repository.client.api;
import org.slf4j.Logger;
@@ -60,6 +60,18 @@ public final class RepositoryClient implements Closeable {
return new BranchCommandBuilder(clientProvider.getBranchCommand());
}
+ public DeleteRemoteBranchCommandBuilder getDeleteRemoteBranchCommand() {
+ logger.trace("delete branch command");
+
+ return new DeleteRemoteBranchCommandBuilder(clientProvider.getDeleteRemoteBranchCommand());
+ }
+
+ public CheckoutCommandBuilder getCheckoutCommand() {
+ logger.trace("create checkout command");
+
+ return new CheckoutCommandBuilder(clientProvider.getCheckoutCommand());
+ }
+
public CommitCommandBuilder getCommitCommand() {
logger.trace("create commit command");
@@ -84,10 +96,16 @@ public final class RepositoryClient implements Closeable {
return new TagCommandBuilder(clientProvider.getTagCommand());
}
+ public MergeCommandBuilder getMergeCommand() {
+ logger.trace("create merge command");
+
+ return new MergeCommandBuilder(clientProvider.getMergeCommand());
+ }
+
public File getWorkingCopy() {
return clientProvider.getWorkingCopy();
}
-
+
public boolean isCommandSupported(ClientCommand command) {
return clientProvider.getSupportedClientCommands().contains(command);
}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/spi/CheckoutCommand.java b/scm-test/src/main/java/sonia/scm/repository/client/spi/CheckoutCommand.java
new file mode 100644
index 0000000000..262ca3894c
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/spi/CheckoutCommand.java
@@ -0,0 +1,35 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import java.io.IOException;
+
+/**
+ * @since 2.4.0
+ */
+public interface CheckoutCommand {
+
+ void checkout(String name) throws IOException;
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/spi/DeleteRemoteBranchCommand.java b/scm-test/src/main/java/sonia/scm/repository/client/spi/DeleteRemoteBranchCommand.java
new file mode 100644
index 0000000000..5dea57f965
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/spi/DeleteRemoteBranchCommand.java
@@ -0,0 +1,32 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import java.io.IOException;
+
+public interface DeleteRemoteBranchCommand {
+
+ void delete(String name) throws IOException;
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/spi/MergeCommand.java b/scm-test/src/main/java/sonia/scm/repository/client/spi/MergeCommand.java
new file mode 100644
index 0000000000..a80031b655
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/spi/MergeCommand.java
@@ -0,0 +1,37 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import sonia.scm.repository.Changeset;
+
+import java.io.IOException;
+
+/**
+ * @since 2.4.0
+ */
+public interface MergeCommand {
+
+ Changeset merge(MergeRequest request) throws IOException;
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/spi/MergeRequest.java b/scm-test/src/main/java/sonia/scm/repository/client/spi/MergeRequest.java
new file mode 100644
index 0000000000..ba7a133cb9
--- /dev/null
+++ b/scm-test/src/main/java/sonia/scm/repository/client/spi/MergeRequest.java
@@ -0,0 +1,89 @@
+/*
+ * MIT License
+ *
+ * Copyright (c) 2020-present Cloudogu GmbH and Contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+package sonia.scm.repository.client.spi;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.base.Objects;
+
+/**
+ * @since 2.4.0
+ */
+public final class MergeRequest {
+
+ private String branch;
+ private String message;
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null)
+ {
+ return false;
+ }
+
+ if (getClass() != obj.getClass())
+ {
+ return false;
+ }
+
+ final MergeRequest other = (MergeRequest) obj;
+
+ return Objects.equal(branch, other.branch)
+ && Objects.equal(message, other.message);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hashCode(branch, message);
+ }
+
+ public void reset() {
+ this.branch = null;
+ this.message = null;
+ }
+
+ @Override
+ public String toString() {
+ return MoreObjects.toStringHelper(this)
+ .add("branch", branch)
+ .add("message", message)
+ .toString();
+ }
+
+ public void setBranch(String branch) {
+ this.branch = branch;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+
+ String getBranch() {
+ return branch;
+ }
+
+ String getMessage() {
+ return message;
+ }
+}
diff --git a/scm-test/src/main/java/sonia/scm/repository/client/spi/RepositoryClientProvider.java b/scm-test/src/main/java/sonia/scm/repository/client/spi/RepositoryClientProvider.java
index feb1d3dd09..bfe4c5afe8 100644
--- a/scm-test/src/main/java/sonia/scm/repository/client/spi/RepositoryClientProvider.java
+++ b/scm-test/src/main/java/sonia/scm/repository/client/spi/RepositoryClientProvider.java
@@ -21,7 +21,7 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
-
+
package sonia.scm.repository.client.spi;
//~--- non-JDK imports --------------------------------------------------------
@@ -87,6 +87,14 @@ public abstract class RepositoryClientProvider implements Closeable
throw new ClientCommandNotSupportedException(ClientCommand.BRANCH);
}
+ public DeleteRemoteBranchCommand getDeleteRemoteBranchCommand() {
+ throw new ClientCommandNotSupportedException(ClientCommand.DELETE_REMOTE_BRANCH);
+ }
+
+ public CheckoutCommand getCheckoutCommand() {
+ throw new ClientCommandNotSupportedException(ClientCommand.CHECKOUT);
+ }
+
/**
* Method description
*
@@ -131,6 +139,10 @@ public abstract class RepositoryClientProvider implements Closeable
throw new ClientCommandNotSupportedException(ClientCommand.TAG);
}
+ public MergeCommand getMergeCommand() {
+ throw new ClientCommandNotSupportedException(ClientCommand.MERGE);
+ }
+
/**
* Returns the working copy of the repository client.
*