From b30a97948ed38a8d6a260ecf0e9e191ec2c216dd Mon Sep 17 00:00:00 2001 From: Konstantin Schaper Date: Tue, 15 Sep 2020 15:48:22 +0200 Subject: [PATCH] implement git rebase --- .../scm/repository/api/MergeStrategy.java | 3 +- .../scm/repository/spi/GitMergeCommand.java | 6 +- .../scm/repository/spi/GitMergeRebase.java | 97 ++++++++++++++++++ .../repository/spi/GitMergeCommandTest.java | 37 +++++++ .../scm/repository/spi/scm-git-spi-test.zip | Bin 40559 -> 46616 bytes 5 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeRebase.java diff --git a/scm-core/src/main/java/sonia/scm/repository/api/MergeStrategy.java b/scm-core/src/main/java/sonia/scm/repository/api/MergeStrategy.java index 98a9938346..180751b4bd 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/MergeStrategy.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/MergeStrategy.java @@ -27,5 +27,6 @@ package sonia.scm.repository.api; public enum MergeStrategy { MERGE_COMMIT, FAST_FORWARD_IF_POSSIBLE, - SQUASH + SQUASH, + REBASE } 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 bd4e6b26b5..38b6b6dee5 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 @@ -60,7 +60,8 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand private static final Set STRATEGIES = ImmutableSet.of( MergeStrategy.MERGE_COMMIT, MergeStrategy.FAST_FORWARD_IF_POSSIBLE, - MergeStrategy.SQUASH + MergeStrategy.SQUASH, + MergeStrategy.REBASE ); @Inject @@ -94,6 +95,9 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand case MERGE_COMMIT: return inClone(clone -> new GitMergeCommit(clone, request, context, repository), workingCopyFactory, request.getTargetBranch()); + case REBASE: + return inClone(clone -> new GitMergeRebase(clone, request, context, repository), workingCopyFactory, request.getTargetBranch()); + default: throw new MergeStrategyNotSupportedException(repository, request.getMergeStrategy()); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeRebase.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeRebase.java new file mode 100644 index 0000000000..d5ba0c49ba --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeRebase.java @@ -0,0 +1,97 @@ +/* + * 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.spi; + +import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.MergeCommand; +import org.eclipse.jgit.api.RebaseResult; +import org.eclipse.jgit.api.errors.GitAPIException; +import org.eclipse.jgit.lib.ObjectId; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import sonia.scm.repository.InternalRepositoryException; +import sonia.scm.repository.Repository; +import sonia.scm.repository.api.MergeCommandResult; + +import java.io.IOException; +import java.util.Collections; +import java.util.Optional; + +public class GitMergeRebase extends GitMergeStrategy { + + private static final Logger logger = LoggerFactory.getLogger(GitMergeRebase.class); + + private final MergeCommandRequest request; + + GitMergeRebase(Git clone, MergeCommandRequest request, GitContext context, Repository repository) { + super(clone, request, context, repository); + this.request = request; + } + + @Override + MergeCommandResult run() throws IOException { + RebaseResult result; + String branchToMerge = request.getBranchToMerge(); + String targetBranch = request.getTargetBranch(); + try { + checkOutBranch(branchToMerge); + result = + getClone() + .rebase() + .setUpstream(targetBranch) + .call(); + } catch (GitAPIException e) { + throw new InternalRepositoryException(getContext().getRepository(), "could not merge branch " + branchToMerge + " into " + targetBranch, e); + } + + if (result.getStatus().isSuccessful()) { + return fastForwardTargetBranch(branchToMerge, targetBranch, result); + } else { + logger.info("could not rebase branch {} into {} with rebase status '{}' due to ...", branchToMerge, targetBranch, result.getStatus()); + logger.info("... conflicts: {}", result.getConflicts()); + logger.info("... failing paths: {}", result.getFailingPaths()); + logger.info("... message: {}", result); + return MergeCommandResult.failure(branchToMerge, targetBranch, Optional.ofNullable(result.getConflicts()).orElse(Collections.singletonList("UNKNOWN"))); + } + } + + private MergeCommandResult fastForwardTargetBranch(String branchToMerge, String targetBranch, RebaseResult result) throws IOException { + try { + getClone().checkout().setName(targetBranch).call(); + ObjectId sourceRevision = resolveRevision(branchToMerge); + getClone() + .merge() + .setFastForward(MergeCommand.FastForwardMode.FF_ONLY) + .setCommit(false) // we want to set the author manually + .include(branchToMerge, sourceRevision) + .call(); + push(); + return MergeCommandResult.success(getTargetRevision().name(), branchToMerge, sourceRevision.name()); + } catch (GitAPIException e) { + return MergeCommandResult.failure(branchToMerge, targetBranch, result.getConflicts()); + } + + } +} 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 716b172981..af9755af3a 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 @@ -473,6 +473,43 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase { } + @Test + public void shouldAllowMergeWithRebase() throws IOException, GitAPIException { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("master"); + request.setBranchToMerge("mergeable"); + request.setMergeStrategy(MergeStrategy.REBASE); + request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det")); + + 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(); + assertThat(mergeCommit.getParentCount()).isEqualTo(1); + assertThat(mergeCommit.getParent(0).name()).isEqualTo("fcd0ef1831e4002ac43ea539f4094334c79ea9ec"); + assertThat(mergeCommit.getName()).isEqualTo(mergeCommandResult.getNewHeadRevision()); + assertThat(mergeCommit.getName()).doesNotStartWith("91b99de908fcd04772798a31c308a64aea1a5523"); + } + + @Test + public void shouldRejectRebaseMergeIfBranchCannotBeRebased() { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("master"); + request.setBranchToMerge("not-rebasable"); + request.setMergeStrategy(MergeStrategy.REBASE); + request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det")); + + MergeCommandResult mergeCommandResult = command.merge(request); + + assertThat(mergeCommandResult.isSuccess()).isFalse(); + + } + private GitMergeCommand createCommand() { return createCommand(git -> { }); diff --git a/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test.zip b/scm-plugins/scm-git-plugin/src/test/resources/sonia/scm/repository/spi/scm-git-spi-test.zip index 80483d04d1d77a446b75a353ad72e2f0a644f2f3..98b05f1002ff5ccef52857f7fc947e2d361bbbf1 100644 GIT binary patch literal 46616 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 delta 17831 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 bNc!J3#7El#H$@N@!9UaCf#N1e2*UpX6Pphe