Merged in bugfix/merge_failures_without_conflicts (pull request #413)

Handle unexpected merge results
This commit is contained in:
Eduard Heimbuch
2020-02-27 09:35:43 +00:00
6 changed files with 89 additions and 4 deletions

View File

@@ -88,7 +88,14 @@ abstract class GitMergeStrategy extends AbstractGitCommand.GitCloneWorker<MergeC
}
MergeCommandResult analyseFailure(MergeResult result) {
logger.info("could not merge branch {} into {} due to conflict in paths {}", branchToMerge, targetBranch, result.getConflicts().keySet());
logger.info("could not merge branch {} into {} with merge status '{}' due to ...", branchToMerge, targetBranch, result.getMergeStatus());
logger.info("... conflicts: {}", result.getConflicts());
logger.info("... checkout conflicts: {}", result.getCheckoutConflicts());
logger.info("... failing paths: {}", result.getFailingPaths());
logger.info("... message: {}", result);
if (result.getConflicts() == null) {
throw new UnexpectedMergeResultException(getRepository(), result);
}
return MergeCommandResult.failure(targetRevision.name(), revisionToMerge.name(), result.getConflicts().keySet());
}
}

View File

@@ -0,0 +1,27 @@
package sonia.scm.repository.spi;
import org.eclipse.jgit.api.MergeResult;
import sonia.scm.ContextEntry;
import sonia.scm.ExceptionWithContext;
import sonia.scm.repository.Repository;
class UnexpectedMergeResultException extends ExceptionWithContext {
public static final String CODE = "4GRrgkSC01";
public UnexpectedMergeResultException(Repository repository, MergeResult result) {
super(ContextEntry.ContextBuilder.entity(repository).build(), createMessage(result));
}
private static String createMessage(MergeResult result) {
return "unexpected merge result: " + result
+ "\nconflicts: " + result.getConflicts()
+ "\ncheckout conflicts: " + result.getCheckoutConflicts()
+ "\nfailing paths: " + result.getFailingPaths();
}
@Override
public String getCode() {
return CODE;
}
}

View File

@@ -113,5 +113,4 @@ public class AbstractGitCommandTestBase extends ZippedRepositoryTestBase
/** Field description */
private GitContext context;
private ScmTransportProtocol scmTransportProtocol;
}

View File

@@ -12,16 +12,23 @@ import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Rule;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;
import sonia.scm.NoChangesMadeException;
import sonia.scm.NotFoundException;
import sonia.scm.repository.GitWorkdirFactory;
import sonia.scm.repository.Person;
import sonia.scm.repository.api.MergeCommandResult;
import sonia.scm.repository.api.MergeStrategy;
import sonia.scm.repository.util.WorkdirProvider;
import sonia.scm.user.User;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import static org.assertj.core.api.Assertions.assertThat;
@@ -163,11 +170,34 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
assertThat(mergeCommandResult.getFilesWithConflict()).containsExactly("a.txt");
}
@Test
public void shouldHandleUnexpectedMergeResults() {
GitMergeCommand command = createCommand(git -> {
try {
FileWriter fw = new FileWriter(new File(git.getRepository().getWorkTree(), "b.txt"), true);
BufferedWriter bw = new BufferedWriter(fw);
bw.write("change");
bw.newLine();
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
});
MergeCommandRequest request = new MergeCommandRequest();
request.setBranchToMerge("mergeable");
request.setTargetBranch("master");
request.setMergeStrategy(MergeStrategy.MERGE_COMMIT);
request.setAuthor(new Person("Dirk Gently", "dirk@holistic.det"));
request.setMessageTemplate("simple");
Assertions.assertThrows(UnexpectedMergeResultException.class, () -> command.merge(request));
}
@Test
public void shouldTakeAuthorFromSubjectIfNotSet() throws IOException, GitAPIException {
SimplePrincipalCollection principals = new SimplePrincipalCollection();
principals.add("admin", REALM);
principals.add( new User("dirk", "Dirk Gently", "dirk@holistic.det"), REALM);
principals.add(new User("dirk", "Dirk Gently", "dirk@holistic.det"), REALM);
shiro.setSubject(
new Subject.Builder()
.principals(principals)
@@ -364,6 +394,20 @@ public class GitMergeCommandTest extends AbstractGitCommandTestBase {
}
private GitMergeCommand createCommand() {
return new GitMergeCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider()));
return createCommand(git -> {
});
}
private GitMergeCommand createCommand(Consumer<Git> interceptor) {
return new GitMergeCommand(createContext(), repository, new SimpleGitWorkdirFactory(new WorkdirProvider())) {
@Override
<R, W extends GitCloneWorker<R>> R inClone(Function<Git, W> workerSupplier, GitWorkdirFactory workdirFactory, String initialBranch) {
Function<Git, W> interceptedWorkerSupplier = git -> {
interceptor.accept(git);
return workerSupplier.apply(git);
};
return super.inClone(interceptedWorkerSupplier, workdirFactory, initialBranch);
}
};
}
}

View File

@@ -199,6 +199,10 @@
"8LRncum0S1": {
"displayName": "Interner Fehler im Repository",
"description": "Bei der Bearbeitung des internen Repositories ist ein Fehler oder ein unerwarteter Zustand aufgetreten. Bitte prüfen Sie die Logs für weitere Informationen."
},
"4GRrgkSC01": {
"displayName": "Unerwartetes Merge-Ergebnis",
"description": "Der Merge hatte ein unerwartetes Ergebis, das nicht automatisiert behandelt werden konnte. Nähere Details sind im Log zu finden. Führen Sie den Merge ggf. manuell durch."
}
},
"namespaceStrategies": {

View File

@@ -199,6 +199,10 @@
"8LRncum0S1": {
"displayName": "Internal repository error",
"description": "There was an error or an unexpected condition while handling the native repository. Please consult the logs for further information."
},
"4GRrgkSC01": {
"displayName": "Unexpected merge result",
"description": "The merge led to an unexpected result, that could not be handled automatically. More details could be found in the log. Please merge the branches manually."
}
},
"namespaceStrategies": {