Fixing the CHANGELOG

We need to do something about our changelogs. First I will explain the
problem, then I will propose a couple solutions.

When we make a change, that change should be committed to the master
branch. Ideally, that change would also include an entry in the
CHANGELOG file. If it's a bugfix, we'll propagate the change up to each
release branch (3-0-stable, 3-1-stable, etc).

We have headings in each CHANGELOG. The heading is a version of rails,
and all entries below each heading are supposed to be changes in that
particular version.

This causes a huge problem when backporting. Let's say we commit
a bugfix to master. At the time of commit, we're not sure if it will be
backported, so we add an entry under the current 3.2 heading. Later we
decide it should be backported. Now we have to merge the commit to the
release branch, then add another commit to master moving the changelog
entry underneath the 3.1.x heading.

We can also have the problem in the opposite direction. Say we need to
revert a change on the release branch and move the commit back to the
3.2 release. Now we must make another commit on master to fix the
location of changelog comment.

I think this way of changelog management is not only very cumbersome,
but also very error prone. There are many ways that we can lose
changelog entries, or simply have them in the wrong place.

I think there are a couple ways to solve this problem, but we (the core
team) need to agree on it.

1) Remove the version headings from the CHANGELOG and simply keep
entries in a reverse chronological order. This is how we keep
changelogs in ruby-core[1].

Actual changelog entries for a particular release can be determined via
git diff and the release tags.

Upsides are that it's easy to merge and easy to revert. The downside is
that we need to include a timestamp and agree on a timezone that we use
for the changelog entries. Vim and Emacs handle this automatically.

2) Just remove the CHANGELOG file all together. We can generate a
changelog via `git log` on release of rails. The upside is that we
don't need to worry about updating the changelog. The downside is that
we put the burden on the release manager to assemble a changelog at
release time. Another alternative could be to just not release a
changelog at all and ask users to read the git log between tags.

Anyway, these are my thoughts. Input is definitely welcome, but I
really think this is something we need to change.

I like the first one, as I think it would be easier to maintain. I don't think people will appreciate the second option much, as we're cutting a lot of noise in the CHANGELOG file and it seems easier to follow than `git log`

- Prem

I suggest using git-notes to mark commits for the CHANGELOG. Metadata FTW!

Not all changes are worth mentioning in the CHANGELOG. But with git-notes, you can annotate commits with additional comments after the commit is made. You can tag commits that you want in the CHANGELOG and then assemble the CHANGELOG by a script in any fashion you want. You can even see these notes on GitHub:

https://github.com/blog/707-git-notes-display

I don’t know if you’d want to just tag the commits or add extra information for the CHANGELOG entry, but I’m sure the core team can figure out how they want to manage that.

Forgot to include a link to what the ruby-core changelog looks like:

  https://github.com/ruby/ruby/blob/trunk/ChangeLog

I'm definitely not keen on option 2.

Option 1 I could live with, though I'd like to still keep the Markdown
format.

Another alternative is to actually just keep the stable release
changelogs in the stable branch. So changelog entries between 3.1.0 and
3.1.1 would only exist in the 3-1-stable branch. Then we wouldn't have
to fuss about keep master in sync.

I don't understand this solution. You're proposing no changelog on
master?

Not exactly. Best explained by example.

SCENE 1

master:

You can't for sure know that you'll backport from master to 3-1-stable.
Also, if you do port to 3-1-stable and someone reverts, now your
changelog entry is lost. I think this suffers exactly the same
problems I mentioned in the original post.

I think Josh's suggestion makes a lot of sense and would seem to solve the issues your present Aaron.

Hey guys,

How about this:

Any commit that should end up in the changelog is tagged, using for example “@changelog” or maybe using git-notes, and then using a separate gem (Which I can develop if you all agree on this solution), that parses git-log between two tags and include any commit having the tag even if it’s a revert, except if the commit is both tagged and reverted (a change that was tagged but was reverted for some reason), at the end generate a changeLog file with the desired formatting…

Using something like this, you can just remove the changelog from all branches and never worry about forgetting or back-porting an entry.

  1. Tag the new version

  2. Run old_version new_version

  3. Include the ChangeLog with his release annoucement

The only problem I can foresee for this solution is current commits, they won’t have any tags, but this can be easily fixed using git-notes, just annotate any commit that should be included with an @changelog note.

Thoughts?

+1 on considering git-notes. Seems to solve the root problems cleanly.

2b) Kill the CHANGELOG and use NEWS-style meaningful release notes instead.

https://github.com/ruby/ruby/blob/trunk/NEWS

https://github.com/ruby/ruby/blob/ruby_1_9_3/NEWS

https://github.com/ruby/ruby/blob/ruby_1_8_7/NEWS

Could the back-porting process be the issue itself?

From what I’ve seen, the example of mongoid changelog is the best way to go. The point is simple: you fix the bug on a specific branch (“3.0.x” for instance) and being on that branch put the changes under the “3.0.x” section. That’s it. You can even release it if you want to.

Just look at it to catch the idea (in breif: several stable branches (where the actual fixes are made) for independent releases; changelogs are populated independently; from time to time branches are merged to master).

Still, mongoid’s changelog is specific to a development and release processes.

I suggest using git-notes to mark commits for the CHANGELOG. Metadata FTW!

Not all changes are worth mentioning in the CHANGELOG. But with git-notes, you can annotate commits with additional comments after the commit is made. You can tag commits that you want in the CHANGELOG and then assemble the CHANGELOG by a script in any fashion you want. You can even see these notes on GitHub:

https://github.com/blog/707-git-notes-display

I don't know if you'd want to just tag the commits or add extra information for the CHANGELOG entry, but I'm sure the core team can figure out how they want to manage that.

Git notes don't buy us much because a revert will not remove the note.
The release manager (or the script we write) would have to reconcile
reverted commits before assembling the changelog:

[aaron@higgins fooo (master)]$ git log
commit 94cf5f7c933bd9590ce5b284a6470c3a142de5b2
Author: Aaron Patterson <aaron.patterson@gmail.com>

No, you don't know for sure when you'll backport. But when you do, you
don't have to change master as well. So when you backport, you create a
new change in 3-1-stable, containing a) the fix and b) a CHANGELOG entry
for 3-1-stable.

When it gets reverted in the 3-1-stable, your changelog entry was in the
backport commit, so that gets reverted too.

Maybe I am misunderstanding the problem?

This is sort-of what I was suggesting with my suggestion that stable
branches are allowed to have different CHANGELOG contents from the
master branch.

We have to deal with:

* New entries in master for the next stable release
* New entries in master that are backported to release branches
* New entries in release branches that are not in master
* Reverts in any of those scenarios

Also, in real life sometimes the changelog entry goes in a different
commit that cannot be squashed because the original commit that forgot
it is already pushed.

Sometimes the changelog entry has a typo or something to fix and it is
edited afterwards.

Also, in the previous months of a major release there's typically *a
lot* of cherry-picking. So much that in the Rails 3 days Rails
Contributors started to count dup'ed entries as one.

This is so changing, that I think we should just accept that the
changelogs should be per release branch. I think that goes in the line
of what Jeremy and Jon suggest. In 3-1-stable you have nothing related
to 3.0, 2.3... anything but 3.1.x. In master you have nothing related
to 3.1 and past releases. If a bug fix is applied to master and
3-1-stable you get an entry for both branches.

The purpose of changelogs is not to have a summarized git log of the
entire history of the module, it is a tool to be able to summarize
what's new *per release*. So per release or per release branch seems
to be a natural fit.

I believe this is easier if it is maintained by hand, and I'd suggest
that pull requests should not create changelog entries, core team
would be responsible for creating an entry at our discretion, as
happened in the past.

Oh, let me add that git notes may also be a good idea.

Since changing or adding a note do not change the SHA1 of the commit,
adding them a posteriori or editing them would work well.

Other pros I see are that you get visibility of what's remarkable in
git log itself, and that's scriptable if we want to build conventional
files for release notes.

With notes, I think changelog entry by release branch happens out of
the box, including cherry-picks, reverts, etc.

My only concern is that the ProGit book mentions a few gotchas related
to pushing and merges. Has that improved in the last versions of Git?

> > Jon fixes a bug in master. It's a minor thing and not hugely relevant to
> > the 3.2.0 release, so there is no changelog entry.
> >
> > SCENE 3
> >
> > Jon backports the fix to 3-1-stable. It's more relevant there as it will
> > feature in the forthcoming point release. So the changelog is updated:
>
> You can't for sure know that you'll backport from master to 3-1-stable.
> Also, if you do port to 3-1-stable and someone reverts, now your
> changelog entry is lost. I think this suffers exactly the same
> problems I mentioned in the original post.

No, you don't know for sure when you'll backport. But when you do, you
don't have to change master as well. So when you backport, you create a
new change in 3-1-stable, containing a) the fix and b) a CHANGELOG entry
for 3-1-stable.

This means that your merge is no longer just a cherry-pick.

When it gets reverted in the 3-1-stable, your changelog entry was in the
backport commit, so that gets reverted too.

So if you revert on 3-1-stable, then do you need to add a changelog
entry to master? If it was changelog worthy for 3-1-stable, surely it
should be changelog worthy on master.

> No, you don't know for sure when you'll backport. But when you do, you
> don't have to change master as well. So when you backport, you create a
> new change in 3-1-stable, containing a) the fix and b) a CHANGELOG entry
> for 3-1-stable.

This means that your merge is no longer just a cherry-pick.

That's true, though I wouldn't find that a big problem as you often have
to resolve conflicts during c-p's anyway.

> When it gets reverted in the 3-1-stable, your changelog entry was in the
> backport commit, so that gets reverted too.

So if you revert on 3-1-stable, then do you need to add a changelog
entry to master? If it was changelog worthy for 3-1-stable, surely it
should be changelog worthy on master.

No: bug fixes are only changelog-worthy on minor releases (i.e.
3-1-stable), not major releases (master). And feature additions should
only be going into master, so would be changelogged there.