mirror of
https://github.com/scm-manager/scm-manager.git
synced 2025-11-06 21:45:43 +01:00
Implement first steps for actual merge
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
package sonia.scm.repository.spi;
|
||||
|
||||
import org.eclipse.jgit.lib.ObjectId;
|
||||
import org.eclipse.jgit.merge.MergeStrategy;
|
||||
import org.eclipse.jgit.merge.ResolveMerger;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import sonia.scm.repository.GitWorkdirFactory;
|
||||
import sonia.scm.repository.InternalRepositoryException;
|
||||
import sonia.scm.repository.api.MergeCommandResult;
|
||||
@@ -12,23 +15,20 @@ import java.io.IOException;
|
||||
|
||||
public class GitMergeCommand extends AbstractGitCommand implements MergeCommand {
|
||||
|
||||
private final GitWorkdirFactory workdirPool;
|
||||
private static final Logger logger = LoggerFactory.getLogger(GitMergeCommand.class);
|
||||
|
||||
GitMergeCommand(GitContext context, sonia.scm.repository.Repository repository, GitWorkdirFactory workdirPool) {
|
||||
private final GitWorkdirFactory workdirFactory;
|
||||
|
||||
GitMergeCommand(GitContext context, sonia.scm.repository.Repository repository, GitWorkdirFactory workdirFactory) {
|
||||
super(context, repository);
|
||||
this.workdirPool = workdirPool;
|
||||
this.workdirFactory = workdirFactory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MergeCommandResult merge(MergeCommandRequest request) {
|
||||
try (WorkingCopy workingCopy = workdirPool.createWorkingCopy(context)) {
|
||||
try (WorkingCopy workingCopy = workdirFactory.createWorkingCopy(context)) {
|
||||
Repository repository = workingCopy.get();
|
||||
ResolveMerger merger = (ResolveMerger) MergeStrategy.RECURSIVE.newMerger(repository);
|
||||
boolean mergeResult = merger.merge(repository.resolve(request.getBranchToMerge()), repository.resolve(request.getTargetBranch()));
|
||||
if (mergeResult) {
|
||||
// TODO push and verify push was successful
|
||||
}
|
||||
return new MergeCommandResult(mergeResult);
|
||||
return new MergeWorker(repository).merge(request);
|
||||
} catch (IOException e) {
|
||||
throw new InternalRepositoryException(e);
|
||||
}
|
||||
@@ -44,4 +44,34 @@ public class GitMergeCommand extends AbstractGitCommand implements MergeCommand
|
||||
throw new InternalRepositoryException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MergeWorker {
|
||||
|
||||
private final Repository clone;
|
||||
private MergeWorker(Repository clone) {
|
||||
this.clone = clone;
|
||||
}
|
||||
|
||||
private MergeCommandResult merge(MergeCommandRequest request) throws IOException {
|
||||
ResolveMerger merger = (ResolveMerger) MergeStrategy.RECURSIVE.newMerger(clone);
|
||||
boolean mergeResult = merger.merge(
|
||||
resolveRevision(clone, request.getTargetBranch()),
|
||||
resolveRevision(clone, request.getBranchToMerge())
|
||||
);
|
||||
if (mergeResult) {
|
||||
logger.info("Merged branch {} into {}", request.getBranchToMerge(), request.getTargetBranch());
|
||||
// TODO commit, push and verify push was successful
|
||||
}
|
||||
return new MergeCommandResult(mergeResult);
|
||||
}
|
||||
|
||||
private ObjectId resolveRevision(Repository repository, String branchToMerge) throws IOException {
|
||||
ObjectId resolved = repository.resolve(branchToMerge);
|
||||
if (resolved == null) {
|
||||
return repository.resolve("origin/" + branchToMerge);
|
||||
} else {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,22 @@ package sonia.scm.repository.spi;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
|
||||
|
||||
public class GitMergeCommandTest extends AbstractGitCommandTestBase {
|
||||
|
||||
@Test
|
||||
public void shouldDetectMergeableBranches() {
|
||||
GitMergeCommand command = createCommand();
|
||||
MergeCommandRequest request = new MergeCommandRequest();
|
||||
request.setBranchToMerge("mergeable");
|
||||
request.setTargetBranch("master");
|
||||
|
||||
boolean mergeable = command.dryRun(request).isMergeable();
|
||||
|
||||
assertThat(mergeable).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldDetectNotMergeableBranches() {
|
||||
GitMergeCommand command = createCommand();
|
||||
@@ -13,10 +28,34 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
|
||||
|
||||
boolean mergeable = command.dryRun(request).isMergeable();
|
||||
|
||||
Assert.assertFalse(mergeable);
|
||||
assertThat(mergeable).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldMergeMergeableBranches() {
|
||||
GitMergeCommand command = createCommand();
|
||||
MergeCommandRequest request = new MergeCommandRequest();
|
||||
request.setTargetBranch("master");
|
||||
request.setBranchToMerge("mergeable");
|
||||
|
||||
boolean mergeable = command.merge(request).isSuccess();
|
||||
|
||||
assertThat(mergeable).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldNotMergeConflictingBranches() {
|
||||
GitMergeCommand command = createCommand();
|
||||
MergeCommandRequest request = new MergeCommandRequest();
|
||||
request.setBranchToMerge("test-branch");
|
||||
request.setTargetBranch("master");
|
||||
|
||||
boolean mergeable = command.merge(request).isSuccess();
|
||||
|
||||
assertThat(mergeable).isFalse();
|
||||
}
|
||||
|
||||
private GitMergeCommand createCommand() {
|
||||
return new GitMergeCommand(createContext(), repository, null);
|
||||
return new GitMergeCommand(createContext(), repository, new SimpleGitWorkdirFactory());
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user