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 be91d06361..64fbadd5a2 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 @@ -62,12 +62,24 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand try { Repository repository = context.open(); ResolveMerger merger = (ResolveMerger) MergeStrategy.RECURSIVE.newMerger(repository, true); - return new MergeDryRunCommandResult(merger.merge(repository.resolve(request.getBranchToMerge()), repository.resolve(request.getTargetBranch()))); + return new MergeDryRunCommandResult( + merger.merge( + resolveRevisionOrThrowNotFound(repository, request.getBranchToMerge()), + resolveRevisionOrThrowNotFound(repository, request.getTargetBranch()))); } catch (IOException e) { throw new InternalRepositoryException(context.getRepository(), "could not clone repository for merge", e); } } + private ObjectId resolveRevisionOrThrowNotFound(Repository repository, String revision) throws IOException { + ObjectId resolved = repository.resolve(revision); + if (resolved == null) { + throw notFound(entity("revision", revision).in(context.getRepository())); + } else { + return resolved; + } + } + private class MergeWorker { private final String target; @@ -110,9 +122,6 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand private void checkOutTargetAsNewLocalBranch() throws IOException { try { ObjectId targetRevision = resolveRevision(target); - if (targetRevision == null) { - throw notFound(entity("revision", target).in(context.getRepository())); - } clone.checkout().setStartPoint(targetRevision.getName()).setName(target).setCreateBranch(true).call(); } catch (RefNotFoundException e) { logger.debug("could not checkout target branch {} for merge as local branch", target, e); @@ -126,9 +135,6 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand MergeResult result; try { ObjectId sourceRevision = resolveRevision(toMerge); - if (sourceRevision == null) { - throw notFound(entity("revision", toMerge).in(context.getRepository())); - } result = clone.merge() .setFastForward(FastForwardMode.NO_FF) .setCommit(false) // we want to set the author manually @@ -190,10 +196,10 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand return MergeCommandResult.failure(result.getConflicts().keySet()); } - private ObjectId resolveRevision(String branchToMerge) throws IOException { - ObjectId resolved = clone.getRepository().resolve(branchToMerge); + private ObjectId resolveRevision(String revision) throws IOException { + ObjectId resolved = clone.getRepository().resolve(revision); if (resolved == null) { - return clone.getRepository().resolve("origin/" + branchToMerge); + return resolveRevisionOrThrowNotFound(clone.getRepository(), "origin/" + revision); } else { return resolved; } 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 7e50b48b9a..c926935496 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 @@ -16,12 +16,14 @@ import org.junit.After; import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import sonia.scm.NotFoundException; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.Person; import sonia.scm.repository.PreProcessorUtil; import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.api.HookContextFactory; import sonia.scm.repository.api.MergeCommandResult; +import sonia.scm.repository.api.MergeDryRunCommandResult; import sonia.scm.user.User; import java.io.IOException; @@ -220,6 +222,46 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase { assertThat(new String(contentOfFileB)).isEqualTo("b\ncontent from branch\n"); } + @Test(expected = NotFoundException.class) + public void shouldHandleNotExistingSourceBranchInMerge() { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("mergeable"); + request.setBranchToMerge("not_existing"); + + command.merge(request); + } + + @Test(expected = NotFoundException.class) + public void shouldHandleNotExistingTargetBranchInMerge() { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("not_existing"); + request.setBranchToMerge("master"); + + command.merge(request); + } + + @Test(expected = NotFoundException.class) + public void shouldHandleNotExistingSourceBranchInDryRun() { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("mergeable"); + request.setBranchToMerge("not_existing"); + + command.dryRun(request); + } + + @Test(expected = NotFoundException.class) + public void shouldHandleNotExistingTargetBranchInDryRun() { + GitMergeCommand command = createCommand(); + MergeCommandRequest request = new MergeCommandRequest(); + request.setTargetBranch("not_existing"); + request.setBranchToMerge("master"); + + command.dryRun(request); + } + private GitMergeCommand createCommand() { return new GitMergeCommand(createContext(), repository, new SimpleGitWorkdirFactory()); }