Skip to content

Commit a7c8875

Browse files
MarkEWaitebasil
authored andcommitted
[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 d3e647d commit a7c8875

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
@@ -1300,7 +1300,8 @@ public void abort() {
13001300

13011301
@Override
13021302
public void execute() throws GitException, InterruptedException {
1303-
ArgumentListBuilder args = new ArgumentListBuilder(gitExe, "log", "--raw", "--no-abbrev", "-M");
1303+
ArgumentListBuilder args =
1304+
new ArgumentListBuilder(gitExe, "log", "--raw", "--no-merges", "--no-abbrev", "-M");
13041305
if (isAtLeastVersion(1, 8, 3, 0)) {
13051306
args.add("--format=" + RAW);
13061307
} else {

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

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,15 +1394,16 @@ public void execute() throws GitException {
13941394
this.includes("HEAD");
13951395
}
13961396
for (RevCommit commit : walk) {
1397-
// git log --raw doesn't show the merge commits unless -m is given
1397+
// git log --raw --no-merges doesn't show merge commits
13981398
if (commit.getParentCount() > 1) {
13991399
continue;
14001400
}
14011401

14021402
formatter.format(commit, null, pw, true);
14031403
}
14041404
} catch (IOException e) {
1405-
throw new GitException("Error: jgit log --raw in " + workspace + " " + e.getMessage(), e);
1405+
throw new GitException(
1406+
"Error: jgit log --raw --no-merges in " + workspace + " " + e.getMessage(), e);
14061407
} finally {
14071408
closeResources();
14081409
}
@@ -1444,7 +1445,7 @@ private String statusOf(DiffEntry d) {
14441445
* Commit to format.
14451446
* @param parent
14461447
* Optional parent commit to produce the diff against. This only matters
1447-
* for merge commits, and git-log behaves differently with respect to this.
1448+
* for merge commits and git-log behaves differently with respect to this.
14481449
*/
14491450
@SuppressFBWarnings(
14501451
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)