From 9a98d04d2ace884012a368620c119e414a2d95ee Mon Sep 17 00:00:00 2001 From: Rafael S Curciel Date: Mon, 27 Jan 2025 20:58:43 +0100 Subject: [PATCH] Add option to suppress merge commits diff in showRevision --- .../plugins/gitclient/CliGitAPIImpl.java | 15 ++++++- .../plugins/gitclient/GitClient.java | 25 +++++++++++ .../plugins/gitclient/JGitAPIImpl.java | 14 ++++-- .../plugins/gitclient/RemoteGitImpl.java | 6 +++ .../plugins/gitclient/GitAPITestUpdate.java | 43 +++++++++++++++++++ 5 files changed, 98 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java b/src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java index 5f38704bf5..e214365945 100644 --- a/src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java +++ b/src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java @@ -1342,12 +1342,23 @@ public List showRevision(ObjectId from, ObjectId to) throws GitException return showRevision(from, to, true); } - /** {@inheritDoc} */ @Override public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput) throws GitException, InterruptedException { + return showRevision(from, to, useRawOutput, false); + } + + /** {@inheritDoc} */ + @Override + public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput, Boolean suppressMergeCommitDiff) + throws GitException, InterruptedException { ArgumentListBuilder args = - new ArgumentListBuilder("log", "--full-history", "--no-abbrev", "--format=raw", "-M", "-m"); + new ArgumentListBuilder("log", "--full-history", "--no-abbrev", "--format=raw", "-M"); + + if (!suppressMergeCommitDiff) { + args.add("-m"); + } + if (useRawOutput) { args.add("--raw"); } diff --git a/src/main/java/org/jenkinsci/plugins/gitclient/GitClient.java b/src/main/java/org/jenkinsci/plugins/gitclient/GitClient.java index 098db17496..2ee34e6bb6 100644 --- a/src/main/java/org/jenkinsci/plugins/gitclient/GitClient.java +++ b/src/main/java/org/jenkinsci/plugins/gitclient/GitClient.java @@ -950,6 +950,31 @@ void submoduleUpdate(boolean recursive, boolean remoteTracking, String reference List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput) throws GitException, InterruptedException; + /** + * Given a Revision, show it as if it were an entry from git whatchanged, so that it + * can be parsed by GitChangeLogParser. + * + *

+ * If useRawOutput is true, the '--raw' option will include commit file information to be passed to the + * GitChangeLogParser. + * + *

+ * Changes are computed on the [from..to] range. If {@code from} is null, this prints + * just one commit that {@code to} represents. + * + *

+ * If suppressMergeCommitDiff is false, for merge commit this method reports one diff per each parent. + * + * @param from a {@link org.eclipse.jgit.lib.ObjectId} object. + * @param to a {@link org.eclipse.jgit.lib.ObjectId} object. + * @param useRawOutput a {java.lang.Boolean} object. + * @param suppressMergeCommitDiff a {java.lang.Boolean} object. + * @return The git whatchanged output, in raw format. + * @throws hudson.plugins.git.GitException if underlying git operation fails. + * @throws java.lang.InterruptedException if interrupted. + */ + List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput, Boolean suppressMergeCommitDiff) + throws GitException, InterruptedException; /** * Equivalent of "git-describe --tags". * diff --git a/src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java b/src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java index a33c89eb43..a6c5d244fa 100644 --- a/src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java +++ b/src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java @@ -2438,6 +2438,13 @@ public List showRevision(ObjectId from, ObjectId to) throws GitException /** {@inheritDoc} */ @Override public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput) throws GitException { + return showRevision(from, to, useRawOutput, false); + } + + /** {@inheritDoc} */ + @Override + public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput, Boolean suppressMergeCommitDiff) + throws GitException { try (Repository repo = getRepository(); ObjectReader or = repo.newObjectReader(); RevWalk w = new RevWalk(or)) { @@ -2457,9 +2464,10 @@ public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutpu if (c.getParentCount() <= 1 || !useRawOutput) { f.format(c, null, pw, useRawOutput); } else { - // the effect of the -m option, which makes the diff produce for each parent of a merge commit - for (RevCommit p : c.getParents()) { - f.format(c, p, pw, useRawOutput); + if (!suppressMergeCommitDiff) { + for (RevCommit p : c.getParents()) { + f.format(c, p, pw, useRawOutput); + } } } diff --git a/src/main/java/org/jenkinsci/plugins/gitclient/RemoteGitImpl.java b/src/main/java/org/jenkinsci/plugins/gitclient/RemoteGitImpl.java index 1b5e486838..576716fd34 100644 --- a/src/main/java/org/jenkinsci/plugins/gitclient/RemoteGitImpl.java +++ b/src/main/java/org/jenkinsci/plugins/gitclient/RemoteGitImpl.java @@ -852,6 +852,12 @@ public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutpu return proxy.showRevision(from, to, useRawOutput); } + @Override + public List showRevision(ObjectId from, ObjectId to, Boolean useRawOutput, Boolean suppressMergeCommitDiff) + throws GitException, InterruptedException { + return proxy.showRevision(from, to, useRawOutput); + } + /** {@inheritDoc} */ @Override public boolean hasGitModules(String treeIsh) throws GitException, InterruptedException { diff --git a/src/test/java/org/jenkinsci/plugins/gitclient/GitAPITestUpdate.java b/src/test/java/org/jenkinsci/plugins/gitclient/GitAPITestUpdate.java index 359681f0fc..f799ed0e03 100644 --- a/src/test/java/org/jenkinsci/plugins/gitclient/GitAPITestUpdate.java +++ b/src/test/java/org/jenkinsci/plugins/gitclient/GitAPITestUpdate.java @@ -2046,6 +2046,49 @@ public void testChangelogWithMergeCommitAndMaxLogHistory() throws Exception { assertThat(writer.toString(), is(not(""))); } + @Issue("JENKINS-23606") + @Test + public void testSupressMergeCommitDiffInShowRevision() throws Exception { + w.init(); + w.commitEmpty("init"); + + final String branchBeforeCommit = "branchBeforeCommit"; + w.git.branch(branchBeforeCommit); + + final String fileFromBranch = "fileFromBranch"; + w.git.checkout().ref(branchBeforeCommit).execute(); + w.touch(fileFromBranch, "content-1"); + w.git.add(fileFromBranch); + w.git.commit("commit-in-branch-before-commit"); + + final String fileInMain = "fileInMain"; + w.git.checkout().ref(defaultBranchName).execute(); + w.touch(fileInMain, "content-2"); + w.git.add(fileInMain); + w.git.commit("commit-in-main-after-branch-created"); + String commitSha1 = w.git.revParse("HEAD").name(); + + w.git.merge() + .setGitPluginFastForwardMode(MergeCommand.GitPluginFastForwardMode.NO_FF) + .setRevisionToMerge(w.git.getHeadRev(w.repoPath(), branchBeforeCommit)) + .execute(); + String commitSha2 = w.git.revParse("HEAD").name(); + + final List defaultBehaviour = + w.git.showRevision(ObjectId.fromString(commitSha1), ObjectId.fromString(commitSha2), true); + assertTrue( + "Default behaviour shows merge commits diffs", + defaultBehaviour.stream().anyMatch(e -> e.contains(fileInMain))); + assertTrue( + "Shows file from merged branch", defaultBehaviour.stream().anyMatch(e -> e.contains(fileFromBranch))); + + final List notShowDiffMerge = + w.git.showRevision(ObjectId.fromString(commitSha1), ObjectId.fromString(commitSha2), true, true); + assertTrue("Merge commit diffs aren't shown", !notShowDiffMerge.stream().anyMatch(e -> e.contains(fileInMain))); + assertTrue( + "Shows file from merged branch", notShowDiffMerge.stream().anyMatch(e -> e.contains(fileFromBranch))); + } + /** * inline ${@link hudson.Functions#isWindows()} to prevent a transient * remote classloader issue