From dc6d9cc5eb8bbbff90a16e12fd231cfaa8f062c8 Mon Sep 17 00:00:00 2001 From: Eduard Heimbuch Date: Wed, 18 Dec 2019 11:03:07 +0100 Subject: [PATCH] return revision on merge --- .../repository/api/MergeCommandResult.java | 12 +++- .../java/sonia/scm/repository/spi/Differ.java | 70 ++++++++++--------- .../spi/GitFastForwardIfPossible.java | 3 +- .../scm/repository/spi/GitMergeCommit.java | 12 +++- .../scm/repository/spi/GitMergeStrategy.java | 6 +- .../repository/spi/GitMergeWithSquash.java | 9 ++- .../sonia/scm/repository/spi/GitMerger.java | 17 +++++ .../ui-components/src/repos/LoadingDiff.tsx | 12 +++- .../src/repos/changesets/ChangesetDiff.tsx | 2 +- scm-ui/ui-webapp/public/locales/de/repos.json | 2 +- scm-ui/ui-webapp/public/locales/en/repos.json | 2 +- 11 files changed, 97 insertions(+), 50 deletions(-) create mode 100644 scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMerger.java diff --git a/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandResult.java b/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandResult.java index 53f712cddc..54b57c668f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandResult.java +++ b/scm-core/src/main/java/sonia/scm/repository/api/MergeCommandResult.java @@ -13,17 +13,19 @@ import static java.util.Collections.unmodifiableCollection; */ public class MergeCommandResult { private final Collection filesWithConflict; + private static String mergeCommitRevision; - private MergeCommandResult(Collection filesWithConflict) { + public MergeCommandResult(Collection filesWithConflict, String mergeCommitRevision) { this.filesWithConflict = filesWithConflict; + this.mergeCommitRevision = mergeCommitRevision; } public static MergeCommandResult success() { - return new MergeCommandResult(emptyList()); + return new MergeCommandResult(emptyList(), mergeCommitRevision); } public static MergeCommandResult failure(Collection filesWithConflict) { - return new MergeCommandResult(new HashSet<>(filesWithConflict)); + return new MergeCommandResult(new HashSet<>(filesWithConflict), ""); } /** @@ -41,4 +43,8 @@ public class MergeCommandResult { public Collection getFilesWithConflict() { return unmodifiableCollection(filesWithConflict); } + + public String getMergeCommitRevision() { + return mergeCommitRevision; + } } 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 0204ca4e3c..fdecac6314 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 @@ -2,6 +2,7 @@ package sonia.scm.repository.spi; import com.google.common.base.Strings; import org.eclipse.jgit.diff.DiffEntry; +import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.revwalk.RevCommit; @@ -10,6 +11,8 @@ 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.ContextEntry; +import sonia.scm.NotFoundException; import sonia.scm.repository.GitUtil; import sonia.scm.util.Util; @@ -35,49 +38,48 @@ final class Differ implements AutoCloseable { } private static Differ create(Repository repository, DiffCommandRequest request) throws IOException { - RevWalk walk = new RevWalk(repository); + RevWalk walk = new RevWalk(repository); - ObjectId revision = repository.resolve(request.getRevision()); - RevCommit commit = walk.parseCommit(revision); + ObjectId revision = repository.resolve(request.getRevision()); + if (revision == null) { + throw NotFoundException.notFound(ContextEntry.ContextBuilder.entity("revision not found", request.getRevision())); + } + RevCommit commit; + try { + commit = walk.parseCommit(revision); + } catch (MissingObjectException ex) { + throw NotFoundException.notFound(ContextEntry.ContextBuilder.entity("revision not found", request.getRevision())); + } - walk.markStart(commit); - commit = walk.next(); - TreeWalk treeWalk = new TreeWalk(repository); - treeWalk.reset(); - treeWalk.setRecursive(true); + walk.markStart(commit); + commit = walk.next(); + TreeWalk treeWalk = new TreeWalk(repository); + treeWalk.reset(); + treeWalk.setRecursive(true); - if (Util.isNotEmpty(request.getPath())) - { - treeWalk.setFilter(PathFilter.create(request.getPath())); - } + if (Util.isNotEmpty(request.getPath())) { + treeWalk.setFilter(PathFilter.create(request.getPath())); + } - if (!Strings.isNullOrEmpty(request.getAncestorChangeset())) - { - ObjectId otherRevision = repository.resolve(request.getAncestorChangeset()); - ObjectId ancestorId = GitUtil.computeCommonAncestor(repository, revision, otherRevision); - RevTree tree = walk.parseCommit(ancestorId).getTree(); + if (!Strings.isNullOrEmpty(request.getAncestorChangeset())) { + ObjectId otherRevision = repository.resolve(request.getAncestorChangeset()); + ObjectId ancestorId = GitUtil.computeCommonAncestor(repository, revision, otherRevision); + RevTree tree = walk.parseCommit(ancestorId).getTree(); + treeWalk.addTree(tree); + } else if (commit.getParentCount() > 0) { + RevTree tree = commit.getParent(0).getTree(); + + if (tree != null) { treeWalk.addTree(tree); - } - else if (commit.getParentCount() > 0) - { - RevTree tree = commit.getParent(0).getTree(); - - if (tree != null) - { - treeWalk.addTree(tree); - } - else - { - treeWalk.addTree(new EmptyTreeIterator()); - } - } - else - { + } else { treeWalk.addTree(new EmptyTreeIterator()); } + } else { + treeWalk.addTree(new EmptyTreeIterator()); + } - treeWalk.addTree(commit.getTree()); + treeWalk.addTree(commit.getTree()); return new Differ(commit, walk, treeWalk); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitFastForwardIfPossible.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitFastForwardIfPossible.java index 64a20a33cb..ddca0a78b0 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitFastForwardIfPossible.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitFastForwardIfPossible.java @@ -7,6 +7,7 @@ import sonia.scm.repository.Repository; import sonia.scm.repository.api.MergeCommandResult; import java.io.IOException; +import java.util.Collections; class GitFastForwardIfPossible extends GitMergeStrategy { @@ -22,7 +23,7 @@ class GitFastForwardIfPossible extends GitMergeStrategy { MergeResult fastForwardResult = mergeWithFastForwardOnlyMode(); if (fastForwardResult.getMergeStatus().isSuccessful()) { push(); - return MergeCommandResult.success(); + return new MergeCommandResult(Collections.emptyList(), ""); } else { return fallbackMerge.run(); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommit.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommit.java index 6aa68a0ea8..f527cff900 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommit.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeCommit.java @@ -3,10 +3,17 @@ package sonia.scm.repository.spi; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.MergeCommand; import org.eclipse.jgit.api.MergeResult; +import org.eclipse.jgit.revwalk.RevCommit; +import sonia.scm.ContextEntry; +import sonia.scm.repository.InternalRepositoryException; import sonia.scm.repository.Repository; import sonia.scm.repository.api.MergeCommandResult; import java.io.IOException; +import java.util.Collections; +import java.util.Optional; + +import static sonia.scm.repository.spi.GitMerger.evaluateRevisionFromMergeCommit; class GitMergeCommit extends GitMergeStrategy { @@ -21,11 +28,12 @@ class GitMergeCommit extends GitMergeStrategy { MergeResult result = doMergeInClone(mergeCommand); if (result.getMergeStatus().isSuccessful()) { - doCommit(); + Optional revCommit = doCommit(); push(); - return MergeCommandResult.success(); + return new MergeCommandResult(Collections.emptyList(), evaluateRevisionFromMergeCommit(revCommit)); } else { return analyseFailure(result); } } + } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeStrategy.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeStrategy.java index 1d53b99c99..17b4571820 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeStrategy.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeStrategy.java @@ -6,6 +6,7 @@ import org.eclipse.jgit.api.MergeCommand; import org.eclipse.jgit.api.MergeResult; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.revwalk.RevCommit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.repository.InternalRepositoryException; @@ -14,6 +15,7 @@ import sonia.scm.repository.api.MergeCommandResult; import java.io.IOException; import java.text.MessageFormat; +import java.util.Optional; abstract class GitMergeStrategy extends AbstractGitCommand.GitCloneWorker { @@ -52,9 +54,9 @@ abstract class GitMergeStrategy extends AbstractGitCommand.GitCloneWorker doCommit() { logger.debug("merged branch {} into {}", toMerge, target); - doCommit(MessageFormat.format(determineMessageTemplate(), toMerge, target), author); + return doCommit(MessageFormat.format(determineMessageTemplate(), toMerge, target), author); } private String determineMessageTemplate() { diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeWithSquash.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeWithSquash.java index b688956404..a1e921e8a9 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeWithSquash.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMergeWithSquash.java @@ -2,11 +2,16 @@ package sonia.scm.repository.spi; import org.eclipse.jgit.api.Git; import org.eclipse.jgit.api.MergeResult; +import org.eclipse.jgit.revwalk.RevCommit; import sonia.scm.repository.Repository; import sonia.scm.repository.api.MergeCommandResult; import org.eclipse.jgit.api.MergeCommand; import java.io.IOException; +import java.util.Collections; +import java.util.Optional; + +import static sonia.scm.repository.spi.GitMerger.evaluateRevisionFromMergeCommit; class GitMergeWithSquash extends GitMergeStrategy { @@ -21,9 +26,9 @@ class GitMergeWithSquash extends GitMergeStrategy { MergeResult result = doMergeInClone(mergeCommand); if (result.getMergeStatus().isSuccessful()) { - doCommit(); + Optional revCommit = doCommit(); push(); - return MergeCommandResult.success(); + return new MergeCommandResult(Collections.emptyList(), evaluateRevisionFromMergeCommit(revCommit)); } else { return analyseFailure(result); } diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMerger.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMerger.java new file mode 100644 index 0000000000..87334e5a57 --- /dev/null +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/repository/spi/GitMerger.java @@ -0,0 +1,17 @@ +package sonia.scm.repository.spi; + +import org.eclipse.jgit.revwalk.RevCommit; +import sonia.scm.ContextEntry; +import sonia.scm.repository.InternalRepositoryException; + +import java.util.Optional; + +public class GitMerger { + + static String evaluateRevisionFromMergeCommit(Optional revCommit) { + if (revCommit.isPresent()) { + return revCommit.get().toString().split(" ")[1]; + } + throw new InternalRepositoryException(ContextEntry.ContextBuilder.entity(GitMergeCommit.class, "merge commit failed"), "could not create commit on merge"); + } +} diff --git a/scm-ui/ui-components/src/repos/LoadingDiff.tsx b/scm-ui/ui-components/src/repos/LoadingDiff.tsx index 45b62f9b35..ec782bc968 100644 --- a/scm-ui/ui-components/src/repos/LoadingDiff.tsx +++ b/scm-ui/ui-components/src/repos/LoadingDiff.tsx @@ -7,8 +7,11 @@ import parser from "gitdiff-parser"; import Loading from "../Loading"; import Diff from "./Diff"; import { DiffObjectProps, File } from "./DiffTypes"; +import { NotFoundError } from "../errors"; +import { Notification } from "../index"; +import {withTranslation, WithTranslation} from "react-i18next"; -type Props = DiffObjectProps & { +type Props = WithTranslation & DiffObjectProps & { url: string; defaultCollapse?: boolean; }; @@ -43,7 +46,7 @@ class LoadingDiff extends React.Component { fetchDiff = () => { const { url } = this.props; - this.setState({loading: true}); + this.setState({ loading: true }); apiClient .get(url) .then(response => response.text()) @@ -66,6 +69,9 @@ class LoadingDiff extends React.Component { render() { const { diff, loading, error } = this.state; if (error) { + if (error instanceof NotFoundError) { + return {this.props.t("changesets.noChangesets")}; + } return ; } else if (loading) { return ; @@ -77,4 +83,4 @@ class LoadingDiff extends React.Component { } } -export default LoadingDiff; +export default withTranslation("repos")(LoadingDiff); diff --git a/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx b/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx index 78f4e90cb3..1789cb5517 100644 --- a/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx +++ b/scm-ui/ui-components/src/repos/changesets/ChangesetDiff.tsx @@ -28,7 +28,7 @@ class ChangesetDiff extends React.Component { return {t("changeset.diffNotSupported")}; } else { const url = this.createUrl(changeset); - return ; + return ; } } } diff --git a/scm-ui/ui-webapp/public/locales/de/repos.json b/scm-ui/ui-webapp/public/locales/de/repos.json index df6c534ece..83a7918018 100644 --- a/scm-ui/ui-webapp/public/locales/de/repos.json +++ b/scm-ui/ui-webapp/public/locales/de/repos.json @@ -72,7 +72,7 @@ "changesets": { "errorTitle": "Fehler", "errorSubtitle": "Changesets konnten nicht abgerufen werden", - "noChangesets": "Keine Changesets in diesem Branch gefunden.", + "noChangesets": "Keine Changesets in diesem Branch gefunden. Die Commits könnten gelöscht wurden sein.", "branchSelectorLabel": "Branches", "collapseDiffs": "Auf-/Zuklappen" }, diff --git a/scm-ui/ui-webapp/public/locales/en/repos.json b/scm-ui/ui-webapp/public/locales/en/repos.json index 103e30b825..eaeba49e16 100644 --- a/scm-ui/ui-webapp/public/locales/en/repos.json +++ b/scm-ui/ui-webapp/public/locales/en/repos.json @@ -72,7 +72,7 @@ "changesets": { "errorTitle": "Error", "errorSubtitle": "Could not fetch changesets", - "noChangesets": "No changesets found for this branch.", + "noChangesets": "No changesets found for this branch. The commits could have been removed.", "branchSelectorLabel": "Branches", "collapseDiffs": "Collapse" },