Skip to content

fix(changelog): changelog generator now handles merge commits better#1319

Merged
jsternberg merged 1 commit intomasterfrom
fix/changelog-with-merges
Jun 3, 2019
Merged

fix(changelog): changelog generator now handles merge commits better#1319
jsternberg merged 1 commit intomasterfrom
fix/changelog-with-merges

Conversation

@jsternberg
Copy link
Copy Markdown
Contributor

@jsternberg jsternberg commented Jun 2, 2019

  • docs/SPEC.md updated
  • Test cases written

When the git log contained merges, the changelog generator didn't
necessarily work correctly. First, it would attempt to parse the message
in merge commits which was always wrong and always printed an error
message. Now, the changelog generator is told to just skip those commits
and move on since merge commits won't contain the message we're looking
for anyway.

The second happened with patch releases and feature branches that were
under work for more than a release. If a release was performed on the
maint branch and another commit was done on master before merging
maint back to master, the tree could be constructed in a way where the
previous version commit could not be clearly found such as in this
example from the v0.31.0 release.

* 3204dd2d ci: add codecov.io support to flux (#1273)
*   f0b68507 Merge branch 'maint'
|\
| * ec371174 (tag: v0.30.0) feat(universe): support for dynamic queries (#1284)
* | 2cce6fe4 feat(universe): support for dynamic queries (#1284)
|/
* 32fb2fb7 (tag: v0.29.0) fix(execute): properly use RefCount to reference count tables (#1216)

If the changelog generator encountered this pattern, it was undefined
exactly how it would behave. In this specific scenario, it parsed every
commit on the left branch going back to the root commit and then found
the previous commit on the second side of the branch. The opposite could
happen too and then it would have missed adding the commit from the
other branch.

The changelog generator has now been modified to find the merge base
before it attempts to read the log to prevent searching back through the
entire history. In the above situations, v0.29.0 would be found and
act as a final constraint for parent commits.

The changelog parser has also been modified to use a breadth-first
search instead of depth-first search and it does not use the Log()
method from the go-git library. This is because the go-git library does
not have a way to stop at a specific commit and stop looking at parent
commits. We now limit the breadth-first search of commits to either the
merge base or the previous version commit which should be the same
commit if the release process was followed correctly. A breadth-first
search is used to ensure we get all commit messages from any merges and
don't skip any commits because we reached the terminating commit first.

Fixes #1304.

@codecov-io
Copy link
Copy Markdown

codecov-io commented Jun 2, 2019

Codecov Report

Merging #1319 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master    #1319   +/-   ##
=======================================
  Coverage   53.93%   53.93%           
=======================================
  Files         178      178           
  Lines       27198    27198           
=======================================
  Hits        14668    14668           
  Misses      11104    11104           
  Partials     1426     1426

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3bbf0cc...1520e0d. Read the comment docs.

@jsternberg jsternberg force-pushed the fix/changelog-with-merges branch from a591bd3 to b12df87 Compare June 2, 2019 18:06
commit, log = &prevCommit, prevLog
} else {
log.Printf("invalid commit message %v: %v", commit.Hash, err)
if currCommit.Committer.When.Before(prevCommit.Committer.When) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this When field that actual time that the commit was added relative to other commits?

I have seen dates in the git log that are definitely from way before the commit was added, which must be due to git commit --amend or force push.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is. Git is... not very smart about this. It's what the actual merge-base command does. Here's the code that sets the comparison:

https://github.com/git/git/blob/master/commit-reach.c#L38

The generation that's referenced comes from a commit graph that isn't written to disk unless you explicitly write it to disk so it's almost always empty and isn't exposed by the go-git library.

The generation number would be much better and exactly what would be needed, but it doesn't exist for practical purposes. Git code just seems to use commit dates as a way of trying to reduce the amount of time for practical purposes, but it's obviously not very reliable.

When the git log contained merges, the changelog generator didn't
necessarily work correctly. First, it would attempt to parse the message
in merge commits which was always wrong and always printed an error
message. Now, the changelog generator is told to just skip those commits
and move on since merge commits won't contain the message we're looking
for anyway.

The second happened with patch releases and feature branches that were
under work for more than a release. If a release was performed on the
maint branch and another commit was done on master before merging
maint back to master, the tree could be constructed in a way where the
previous version commit could not be clearly found such as in this
example from the `v0.31.0` release.

    * 3204dd2 ci: add codecov.io support to flux (#1273)
    *   f0b6850 Merge branch 'maint'
    |\
    | * ec37117 (tag: v0.30.0) feat(universe): support for dynamic queries (#1284)
    * | 2cce6fe feat(universe): support for dynamic queries (#1284)
    |/
    * 32fb2fb (tag: v0.29.0) fix(execute): properly use RefCount to reference count tables (#1216)

If the changelog generator encountered this pattern, it was undefined
exactly how it would behave. In this specific scenario, it parsed every
commit on the left branch going back to the root commit and then found
the previous commit on the second side of the branch. The opposite could
happen too and then it would have missed adding the commit from the
other branch.

The changelog generator has now been modified to find the merge base
before it attempts to read the log to prevent searching back through the
entire history. In the above situations, `v0.29.0` would be found and
act as a final constraint for parent commits.

The changelog parser has also been modified to use a breadth-first
search instead of depth-first search and it does not use the `Log()`
method from the go-git library. This is because the go-git library does
not have a way to stop at a specific commit and stop looking at parent
commits. We now limit the breadth-first search of commits to either the
merge base or the previous version commit which should be the same
commit if the release process was followed correctly. A breadth-first
search is used to ensure we get all commit messages from any merges and
don't skip any commits because we reached the terminating commit first.
@jsternberg jsternberg force-pushed the fix/changelog-with-merges branch from b12df87 to 1520e0d Compare June 3, 2019 16:22
@jsternberg
Copy link
Copy Markdown
Contributor Author

I updated the code with comments to explain what I was doing.

@jsternberg jsternberg merged commit c58529c into master Jun 3, 2019
@jsternberg jsternberg deleted the fix/changelog-with-merges branch June 3, 2019 16:25
davidgs pushed a commit to davidgs/flux that referenced this pull request Aug 20, 2019
…nfluxdata#1319)

When the git log contained merges, the changelog generator didn't
necessarily work correctly. First, it would attempt to parse the message
in merge commits which was always wrong and always printed an error
message. Now, the changelog generator is told to just skip those commits
and move on since merge commits won't contain the message we're looking
for anyway.

The second happened with patch releases and feature branches that were
under work for more than a release. If a release was performed on the
maint branch and another commit was done on master before merging
maint back to master, the tree could be constructed in a way where the
previous version commit could not be clearly found such as in this
example from the `v0.31.0` release.

    * 3204dd2 ci: add codecov.io support to flux (influxdata#1273)
    *   f0b6850 Merge branch 'maint'
    |\
    | * ec37117 (tag: v0.30.0) feat(universe): support for dynamic queries (influxdata#1284)
    * | 2cce6fe feat(universe): support for dynamic queries (influxdata#1284)
    |/
    * 32fb2fb (tag: v0.29.0) fix(execute): properly use RefCount to reference count tables (influxdata#1216)

If the changelog generator encountered this pattern, it was undefined
exactly how it would behave. In this specific scenario, it parsed every
commit on the left branch going back to the root commit and then found
the previous commit on the second side of the branch. The opposite could
happen too and then it would have missed adding the commit from the
other branch.

The changelog generator has now been modified to find the merge base
before it attempts to read the log to prevent searching back through the
entire history. In the above situations, `v0.29.0` would be found and
act as a final constraint for parent commits.

The changelog parser has also been modified to use a breadth-first
search instead of depth-first search and it does not use the `Log()`
method from the go-git library. This is because the go-git library does
not have a way to stop at a specific commit and stop looking at parent
commits. We now limit the breadth-first search of commits to either the
merge base or the previous version commit which should be the same
commit if the release process was followed correctly. A breadth-first
search is used to ensure we get all commit messages from any merges and
don't skip any commits because we reached the terminating commit first.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Changelog generator does not work with the release workflow

3 participants