Implement first steps for actual merge

This commit is contained in:
René Pfeuffer
2018-11-07 11:52:49 +01:00
parent 04c5d6f84a
commit e377ce5988
3 changed files with 81 additions and 12 deletions

View File

@@ -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;
}
}
}
}

View File

@@ -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());
}
}