From e533820ae6f939cf27a5096a46fd0c7a546fafbe Mon Sep 17 00:00:00 2001 From: Rene Pfeuffer Date: Mon, 23 Sep 2019 12:16:07 +0200 Subject: [PATCH 1/3] Check for unrelated histories --- .../java/sonia/scm/repository/GitUtil.java | 6 +++-- .../java/sonia/scm/repository/spi/Differ.java | 22 +++++++++++++++++-- .../main/resources/locales/de/plugins.json | 4 ++++ .../main/resources/locales/en/plugins.json | 4 ++++ 4 files changed, 32 insertions(+), 4 deletions(-) diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index 7175d3b646..992e595382 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -70,6 +70,7 @@ import java.util.Optional; import java.util.concurrent.TimeUnit; import static java.util.Optional.of; +import static java.util.Optional.ofNullable; //~--- JDK imports ------------------------------------------------------------ @@ -722,12 +723,13 @@ public final class GitUtil /** * Computes the first common ancestor of two revisions, aka merge base. */ - public static ObjectId computeCommonAncestor(org.eclipse.jgit.lib.Repository repository, ObjectId revision1, ObjectId revision2) throws IOException { + public static Optional computeCommonAncestor(org.eclipse.jgit.lib.Repository repository, ObjectId revision1, ObjectId revision2) throws IOException { try (RevWalk mergeBaseWalk = new RevWalk(repository)) { mergeBaseWalk.setRevFilter(RevFilter.MERGE_BASE); mergeBaseWalk.markStart(mergeBaseWalk.lookupCommit(revision1)); mergeBaseWalk.markStart(mergeBaseWalk.parseCommit(revision2)); - return mergeBaseWalk.next().getId(); + RevCommit commonAncestor = mergeBaseWalk.next(); + return ofNullable(commonAncestor).map(RevCommit::getId); } } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/Differ.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/Differ.java index ca417550f4..81d19886c3 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/Differ.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/Differ.java @@ -10,11 +10,15 @@ import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.treewalk.EmptyTreeIterator; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.treewalk.filter.PathFilter; +import sonia.scm.BadRequestException; import sonia.scm.repository.GitUtil; import sonia.scm.util.Util; import java.io.IOException; import java.util.List; +import java.util.Optional; + +import static java.util.Collections.emptyList; final class Differ implements AutoCloseable { @@ -55,7 +59,9 @@ final class Differ implements AutoCloseable { if (!Strings.isNullOrEmpty(request.getAncestorChangeset())) { ObjectId otherRevision = repository.resolve(request.getAncestorChangeset()); - ObjectId ancestorId = computeCommonAncestor(repository, revision, otherRevision); + ObjectId ancestorId = + computeCommonAncestor(repository, revision, otherRevision) + .orElseThrow(NoCommonHistoryException::new); RevTree tree = walk.parseCommit(ancestorId).getTree(); treeWalk.addTree(tree); } @@ -82,7 +88,7 @@ final class Differ implements AutoCloseable { return new Differ(commit, walk, treeWalk); } - private static ObjectId computeCommonAncestor(org.eclipse.jgit.lib.Repository repository, ObjectId revision1, ObjectId revision2) throws IOException { + private static Optional computeCommonAncestor(org.eclipse.jgit.lib.Repository repository, ObjectId revision1, ObjectId revision2) throws IOException { return GitUtil.computeCommonAncestor(repository, revision1, revision2); } @@ -115,4 +121,16 @@ final class Differ implements AutoCloseable { return entries; } } + + private static class NoCommonHistoryException extends BadRequestException { + + private NoCommonHistoryException() { + super(emptyList(), "no common history"); + } + + @Override + public String getCode() { + return "4iRct4avG1"; + } + } } diff --git a/scm-webapp/src/main/resources/locales/de/plugins.json b/scm-webapp/src/main/resources/locales/de/plugins.json index 9c5bb3f5f5..ef6d5d8c96 100644 --- a/scm-webapp/src/main/resources/locales/de/plugins.json +++ b/scm-webapp/src/main/resources/locales/de/plugins.json @@ -175,6 +175,10 @@ "40RaYIeeR1": { "displayName": "Es wurden keine Änderungen durchgeführt", "description": "Das Repository wurde nicht verändert. Daher konnte kein neuer Commit erzeugt werden." + }, + "4iRct4avG1": { + "displayName": "Die Revisionen haben keinen gemeinsamen Ursprung", + "description": "Die Historie der Revisionen hat keinen gemeinsamen Urspung und kann somit auch nicht gegen einen solchen verglichen werden." } }, "namespaceStrategies": { diff --git a/scm-webapp/src/main/resources/locales/en/plugins.json b/scm-webapp/src/main/resources/locales/en/plugins.json index 1ffffd73b7..247fa212f3 100644 --- a/scm-webapp/src/main/resources/locales/en/plugins.json +++ b/scm-webapp/src/main/resources/locales/en/plugins.json @@ -175,6 +175,10 @@ "40RaYIeeR1": { "displayName": "No changes were made", "description": "No changes were made to the files of the repository. Therefor no new commit could be created." + }, + "4iRct4avG1": { + "displayName": "The revisions have unrelated histories", + "description": "The revisions have unrelated histories. Therefor there is no common commit to compare with." } }, "namespaceStrategies": { From a632350d322d7db5320e122016f734a3ef444025 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 2 Oct 2019 07:43:17 +0200 Subject: [PATCH 2/3] added message to NoCommonHistoryException --- .../java/sonia/scm/repository/NoCommonHistoryException.java | 6 +++++- .../src/main/java/sonia/scm/repository/GitUtil.java | 3 ++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/repository/NoCommonHistoryException.java b/scm-core/src/main/java/sonia/scm/repository/NoCommonHistoryException.java index e63f28cdce..ddb7793d20 100644 --- a/scm-core/src/main/java/sonia/scm/repository/NoCommonHistoryException.java +++ b/scm-core/src/main/java/sonia/scm/repository/NoCommonHistoryException.java @@ -8,7 +8,11 @@ import static java.util.Collections.emptyList; public class NoCommonHistoryException extends BadRequestException { public NoCommonHistoryException() { - super(emptyList(), "no common history"); + this("no common history"); + } + + public NoCommonHistoryException(String message) { + super(emptyList(), message); } @Override diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java index b769b98b18..d726b992ca 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/GitUtil.java @@ -735,7 +735,8 @@ public final class GitUtil mergeBaseWalk.markStart(mergeBaseWalk.parseCommit(revision2)); RevCommit ancestor = mergeBaseWalk.next(); if (ancestor == null) { - throw new NoCommonHistoryException(); + String msg = "revisions %s and %s are not related and therefore do not have a common ancestor"; + throw new NoCommonHistoryException(String.format(msg, revision1.name(), revision2.name())); } return ancestor.getId(); } From b71bea61b311bea4b606323a8e8381802d50ef3b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 2 Oct 2019 06:22:22 +0000 Subject: [PATCH 3/3] Close branch bugfix/merge_with_unrelated_histories