More code is flowing through projects, with people and agents working on changes in parallel. That means more pull requests updating the same changelog, often at the same time.
Two pull requests add unrelated features. Both add a line at the top of
CHANGELOG.md. The code merges cleanly, but the changelog conflicts:
Both entries belong in the changelog. The conflict is straightforward to resolve, but it keeps coming back as more changes land.
A shared changelog puts everyone’s changes in one file, often under the same heading. Git sees competing edits to the same lines, even when the entries describe independent work.
We built changelog-merge to handle this for files that follow Keep a Changelog. It understands releases, categories, and entries. In this example, it keeps both additions:
Enable the integration in your project’s devenv.nix:
changelog-merge.enable = true;
Enter the environment and merge as usual:
devenv configures Git to use the changelog-merge binary to resolve conflicts in
CHANGELOG.md.
For a changelog with a different name, add its path:
changelog-merge.enable = true;
git.attributes = [ "docs/CHANGES.md merge=changelog-merge" ];
Commit your devenv configuration so other contributors get the same setup when they enter the environment. See the integration documentation for more options.
You can use changelog-merge without devenv or Nix. With Rust 1.88 or newer installed, run:
cargo install changelog-merge --version 0.1.0 --locked
Make sure changelog-merge is on your PATH, then check your existing changelog:
changelog-merge check CHANGELOG.md
Add this line to your repository’s .gitattributes:
CHANGELOG.md merge=changelog-merge
Register the merge driver from inside the repository:
git config --local merge.changelog-merge.name 'Keep a Changelog semantic merger'
git config --local merge.changelog-merge.driver 'changelog-merge merge %O %A %B --marker-size %L --path %P'
git config --local merge.changelog-merge.recursive binary
Commit .gitattributes. Each contributor needs to install the executable and
run the three configuration commands in their clone. The attribute travels with
the repository; local Git configuration does not.
Now git merge, git rebase, and git cherry-pick can use changelog-merge
automatically. You can check the setup with:
git check-attr merge -- CHANGELOG.md
git config --get merge.changelog-merge.driver
The first command should report CHANGELOG.md: merge: changelog-merge, and the
second should print the driver command you configured.
If both branches rewrite the same entry incompatibly, changelog-merge leaves conflict markers for you to resolve. It also preserves conflicts when it cannot confidently match changes. Independent additions can merge automatically; competing changes still need a decision.
Try it on your next pair of changelog updates. The source and documentation cover merge behavior and limitations, and we’d like to hear how it works on your project’s changelog.