From 072d8f15c9221967582d4f4084487c9064ed1c4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Pfeuffer?= Date: Thu, 6 Aug 2020 07:58:22 +0200 Subject: [PATCH] Detect merges where branch has been deleted, too --- ...PostReceiveHookMergeDetectionProvider.java | 52 ------------------- .../GitReceiveHookMergeDetectionProvider.java | 39 +++++++++++--- .../spi/GitHookContextProvider.java | 29 +---------- .../java/sonia/scm/web/GitReceiveHook.java | 2 +- 4 files changed, 35 insertions(+), 87 deletions(-) delete mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitPostReceiveHookMergeDetectionProvider.java diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitPostReceiveHookMergeDetectionProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitPostReceiveHookMergeDetectionProvider.java deleted file mode 100644 index e8e41ac3a2..0000000000 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitPostReceiveHookMergeDetectionProvider.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * 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.api; - -import org.eclipse.jgit.lib.Repository; -import sonia.scm.repository.ChangesetPagingResult; -import sonia.scm.repository.spi.GitLogComputer; -import sonia.scm.repository.spi.HookMergeDetectionProvider; -import sonia.scm.repository.spi.LogCommandRequest; - -public class GitPostReceiveHookMergeDetectionProvider implements HookMergeDetectionProvider { - private final Repository repository; - private final String repositoryId; - - public GitPostReceiveHookMergeDetectionProvider(Repository repository, String repositoryId) { - this.repository = repository; - this.repositoryId = repositoryId; - } - - @Override - public boolean branchesMerged(String target, String branch) { - LogCommandRequest request = new LogCommandRequest(); - request.setBranch(branch); - request.setAncestorChangeset(target); - request.setPagingLimit(1); - - ChangesetPagingResult changesets = new GitLogComputer(repositoryId, repository).compute(request); - return changesets.getTotal() == 0; - } -} diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitReceiveHookMergeDetectionProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitReceiveHookMergeDetectionProvider.java index fef5806412..03a5b59837 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitReceiveHookMergeDetectionProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/api/GitReceiveHookMergeDetectionProvider.java @@ -24,33 +24,58 @@ package sonia.scm.repository.api; +import org.eclipse.jgit.lib.AnyObjectId; +import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.transport.ReceiveCommand; +import sonia.scm.repository.GitUtil; import sonia.scm.repository.spi.GitLogComputer; import sonia.scm.repository.spi.HookMergeDetectionProvider; import sonia.scm.repository.spi.LogCommandRequest; +import java.util.List; + public class GitReceiveHookMergeDetectionProvider implements HookMergeDetectionProvider { private final Repository repository; private final String repositoryId; - private final BranchMapper branchMapper; + private final List receiveCommands; - public GitReceiveHookMergeDetectionProvider(Repository repository, String repositoryId, BranchMapper branchMapper) { + public GitReceiveHookMergeDetectionProvider(Repository repository, String repositoryId, List receiveCommands) { this.repository = repository; this.repositoryId = repositoryId; - this.branchMapper = branchMapper; + this.receiveCommands = receiveCommands; } @Override public boolean branchesMerged(String target, String branch) { LogCommandRequest request = new LogCommandRequest(); - request.setBranch(branchMapper.map(branch)); - request.setAncestorChangeset(branchMapper.map(target)); + request.setBranch(findRelevantRevisionForBranchIfToBeUpdated(branch)); + request.setAncestorChangeset(findRelevantRevisionForBranchIfToBeUpdated(target)); request.setPagingLimit(1); return new GitLogComputer(repositoryId, repository).compute(request).getTotal() == 0; } - public interface BranchMapper { - String map(String branch); + private String findRelevantRevisionForBranchIfToBeUpdated(String branch) { + return receiveCommands + .stream() + .filter(receiveCommand -> isReceiveCommandForBranch(branch, receiveCommand)) + .map(this::getRelevantRevision) + .map(AnyObjectId::getName) + .findFirst() + .orElse(branch); + } + + private boolean isReceiveCommandForBranch(String branch, ReceiveCommand receiveCommand) { + return receiveCommand.getType() != ReceiveCommand.Type.CREATE + && GitUtil.getBranch(receiveCommand.getRef()).equals(branch); + } + + private ObjectId getRelevantRevision(ReceiveCommand receiveCommand) { + if (receiveCommand.getType() == ReceiveCommand.Type.DELETE) { + return receiveCommand.getOldId(); + } else { + return receiveCommand.getNewId(); + } } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitHookContextProvider.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitHookContextProvider.java index 755223afc2..bc8d633add 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitHookContextProvider.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitHookContextProvider.java @@ -26,12 +26,9 @@ package sonia.scm.repository.spi; //~--- non-JDK imports -------------------------------------------------------- -import org.eclipse.jgit.lib.AnyObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.transport.ReceivePack; -import sonia.scm.repository.GitUtil; -import sonia.scm.repository.RepositoryHookType; import sonia.scm.repository.api.GitHookBranchProvider; import sonia.scm.repository.api.GitHookMessageProvider; import sonia.scm.repository.api.GitHookTagProvider; @@ -67,20 +64,17 @@ public class GitHookContextProvider extends HookContextProvider /** * Constructs a new instance - * @param receivePack git receive pack + * @param receivePack git receive pack * @param receiveCommands received commands - * @param type */ public GitHookContextProvider( ReceivePack receivePack, List receiveCommands, - RepositoryHookType type, Repository repository, String repositoryId ) { this.receivePack = receivePack; this.receiveCommands = receiveCommands; - this.type = type; this.repository = repository; this.repositoryId = repositoryId; this.changesetProvider = new GitHookChangesetProvider(receivePack, @@ -116,25 +110,7 @@ public class GitHookContextProvider extends HookContextProvider @Override public HookMergeDetectionProvider getMergeDetectionProvider() { - if (type == RepositoryHookType.POST_RECEIVE) { - return new GitReceiveHookMergeDetectionProvider(repository, repositoryId, branch -> branch); - } else { - return new GitReceiveHookMergeDetectionProvider(repository, repositoryId, this::findNewRevisionForBranchIfToBeUpdated); - } - } - - private String findNewRevisionForBranchIfToBeUpdated(String branch) { - return receiveCommands - .stream() - .filter(receiveCommand -> isReceiveCommandForBranch(branch, receiveCommand)) - .map(ReceiveCommand::getNewId) - .map(AnyObjectId::getName) - .findFirst() - .orElse(branch); - } - - private boolean isReceiveCommandForBranch(String branch, ReceiveCommand receiveCommand) { - return GitUtil.getBranch(receiveCommand.getRef()).equals(branch); + return new GitReceiveHookMergeDetectionProvider(repository, repositoryId, receiveCommands); } @Override @@ -146,7 +122,6 @@ public class GitHookContextProvider extends HookContextProvider private final GitHookChangesetProvider changesetProvider; private final List receiveCommands; private final ReceivePack receivePack; - private final RepositoryHookType type; private final Repository repository; private final String repositoryId; } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java index a2d218b99c..a9d74e0357 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitReceiveHook.java @@ -122,7 +122,7 @@ public class GitReceiveHook implements PreReceiveHook, PostReceiveHook logger.trace("resolved repository to {}", repositoryId); - GitHookContextProvider context = new GitHookContextProvider(rpack, receiveCommands, type, repository, repositoryId); + GitHookContextProvider context = new GitHookContextProvider(rpack, receiveCommands, repository, repositoryId); hookEventFacade.handle(repositoryId).fireHookEvent(type, context);