Skip to content

Commit fd896f7

Browse files
committed
[JENKINS-76026] Do not show merges in changelog (jenkinsci#1327)
Git client 6.3.1 adapted the git client plugin to support command line git 2.51.0 where the "whatchanged" command has been deprecated. However, the change introduced an inconsistency between the CLI git implementation and the JGit implementation. Prior to git client plugin 6.3.1, the changelog skipped merge commits in all cases. With git client 6.3.1, the CLI git changelog includes merge commits. With git client 6.3.1, the JGit changelog does not include merge commits. Testing done: * Confirmed the bug with interactive testing of git client plugin 6.3.1 * Wrote an automated test that shows the inconsistency * Confirmed that the automated test fails with git client 6.3.1 and passes with the fix (cherry picked from commit 358e279)
1 parent 7071eb4 commit fd896f7

File tree

4 files changed

+65
-5
lines changed

4 files changed

+65
-5
lines changed

src/main/java/org/jenkinsci/plugins/gitclient/ChangelogCommand.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
* Command builder for generating changelog in the format {@code GitSCM} expects.
99
*
1010
* <p>
11-
* The output format is that of <code>git log --raw</code>, which looks something like this:
11+
* The output format is that of <code>git log --raw --no-merges</code>, which looks something like this:
1212
*
1313
* <pre>
1414
* commit dadaf808d99c4c23c53476b0c48e25a181016300

src/main/java/org/jenkinsci/plugins/gitclient/CliGitAPIImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1297,7 +1297,8 @@ public void abort() {
12971297

12981298
@Override
12991299
public void execute() throws GitException, InterruptedException {
1300-
ArgumentListBuilder args = new ArgumentListBuilder(gitExe, "log", "--raw", "--no-abbrev", "-M");
1300+
ArgumentListBuilder args =
1301+
new ArgumentListBuilder(gitExe, "log", "--raw", "--no-merges", "--no-abbrev", "-M");
13011302
if (isAtLeastVersion(1, 8, 3, 0)) {
13021303
args.add("--format=" + RAW);
13031304
} else {

src/main/java/org/jenkinsci/plugins/gitclient/JGitAPIImpl.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1350,15 +1350,16 @@ public void execute() throws GitException {
13501350
this.includes("HEAD");
13511351
}
13521352
for (RevCommit commit : walk) {
1353-
// git log --raw doesn't show the merge commits unless -m is given
1353+
// git log --raw --no-merges doesn't show merge commits
13541354
if (commit.getParentCount() > 1) {
13551355
continue;
13561356
}
13571357

13581358
formatter.format(commit, null, pw, true);
13591359
}
13601360
} catch (IOException e) {
1361-
throw new GitException("Error: jgit log --raw in " + workspace + " " + e.getMessage(), e);
1361+
throw new GitException(
1362+
"Error: jgit log --raw --no-merges in " + workspace + " " + e.getMessage(), e);
13621363
} finally {
13631364
closeResources();
13641365
}
@@ -1400,7 +1401,7 @@ private String statusOf(DiffEntry d) {
14001401
* Commit to format.
14011402
* @param parent
14021403
* Optional parent commit to produce the diff against. This only matters
1403-
* for merge commits, and git-log behaves differently with respect to this.
1404+
* for merge commits and git-log behaves differently with respect to this.
14041405
*/
14051406
@SuppressFBWarnings(
14061407
value = "VA_FORMAT_STRING_USES_NEWLINE",

src/test/java/org/jenkinsci/plugins/gitclient/GitAPITest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1710,6 +1710,64 @@ public void testChangeLogAbort() throws Exception {
17101710
assertTrue("No SHA1 in " + writer, writer.toString().contains(sha1));
17111711
}
17121712

1713+
@Test
1714+
public void testChangelogSkipsMerges() throws Exception {
1715+
int counter = 0;
1716+
workspace.touch(testGitDir, "file-skips-merges-" + counter, "changelog skips merges " + counter);
1717+
testGitClient.add("file-skips-merges-" + counter);
1718+
testGitClient.commit("skips-merges-" + counter++);
1719+
String rootCommit = testGitClient.revParse("HEAD").name();
1720+
1721+
// Create branches a, b, and common that will merge a and b
1722+
testGitClient.branch("branch-A"); // Create branch-A without switching to it
1723+
testGitClient.branch("branch-B"); // Create branch-B without switching to it
1724+
testGitClient.branch("common"); // common branch that will merge branch-A and branch-B
1725+
1726+
testGitClient.checkoutBranch("branch-A", rootCommit); // Switch to branch-A
1727+
workspace.touch(testGitDir, "file-branch-A", "branch-A file " + counter++);
1728+
testGitClient.add("file-branch-A");
1729+
testGitClient.commit("file-branch-A on branch-A");
1730+
String branchACommit = testGitClient.revParse("HEAD").name();
1731+
1732+
testGitClient.checkoutBranch("branch-B", rootCommit); // Switch to branch-B
1733+
workspace.touch(testGitDir, "file-branch-B", "branch-B file " + counter++);
1734+
testGitClient.add("file-branch-B");
1735+
testGitClient.commit("file-branch-B on branch-B");
1736+
String branchBCommit = testGitClient.revParse("HEAD").name();
1737+
1738+
String mergeMessage = "Merged branch-B into common";
1739+
testGitClient.checkoutBranch("common", rootCommit); // Switch to common branch
1740+
testGitClient
1741+
.merge()
1742+
.setRevisionToMerge(ObjectId.fromString(branchACommit))
1743+
.execute();
1744+
testGitClient
1745+
.merge()
1746+
.setRevisionToMerge(ObjectId.fromString(branchBCommit))
1747+
.setMessage(mergeMessage)
1748+
.execute();
1749+
String mergedCommit = testGitClient.revParse("HEAD").name();
1750+
1751+
workspace.touch(testGitDir, "file-skips-merges-" + counter, "changelog skips merges " + counter);
1752+
testGitClient.add("file-skips-merges-" + counter);
1753+
testGitClient.commit("skips-merges-" + counter++);
1754+
String finalCommit = testGitClient.revParse("HEAD").name();
1755+
1756+
// Calculate the changelog
1757+
StringWriter writer = new StringWriter();
1758+
testGitClient.changelog().to(writer).execute();
1759+
String changelog = writer.toString();
1760+
1761+
// Confirm the changelog includes expected commits
1762+
assertThat(changelog, containsString("commit " + branchACommit));
1763+
assertThat(changelog, containsString("commit " + branchBCommit));
1764+
assertThat(changelog, containsString("commit " + finalCommit));
1765+
1766+
// Confirm the changelog does not include the merge commit
1767+
assertThat(changelog, not(containsString("commit " + mergedCommit)));
1768+
assertThat(changelog, not(containsString(mergeMessage)));
1769+
}
1770+
17131771
/**
17141772
* inline ${@link hudson.Functions#isWindows()} to prevent a transient remote classloader issue
17151773
*/

0 commit comments

Comments
 (0)