Home > Mobile >  Can you force manual merge for a text file in a git repository?
Can you force manual merge for a text file in a git repository?

Time:01-28

Motivation

In our software development, it often happens that multiple developers make changes to the CHANGELOG.md at the same time. Let's say our master branch looks like this.

## Unreleased

change X
change Y

If on one branch, we create a new release:

## Unreleased

## [1.0.0] - 2023-01-27

change X
change Y

While on another change Z is introduced:

## Unreleased

change X
change Y
change Z

If the change branch gets merged after the release branch, the automatic merge will most likely happily merge the CHANGELOG.md like so:

## Unreleased

## [1.0.0] - 2023-01-27

change X
change Y
change Z

Change Z was placed under the release even though it is not part of it!

The correct CHANGELOG.md looks like this:

## Unreleased

change Z

## [1.0.0] - 2023-01-27

change X
change Y

Question

We do not have automated tests for our changelog and so I would like to know if it is possible to force developers to manually merge the changelog whenever parallel changes were made (on three-way merge).

At the same time, I want our tooling (VSCode) to consider the CHANGELOG.md file a text file.

Ideally, no one on the team would have to execute any manual steps after cloning.

What I've already tried

I added a .gitattributes file and played with the diff and merge attributes.

CHANGELOG.md -merge diff

While unsetting the merge attribute with -merge does force a merge, the file is treated as a binary despite setting the diff attribute with diff. I tried a few more combinations but so far I have not found a combination that both:

  1. allows me to view the diffs as text
  2. forces a manual resolution of three-way merges (forces conflicts)

CodePudding user response:

On fixing merges

  1. Merge like normal: merge <branch-name>
  2. If the merge stops with conflicts, resolve them in whatever way you choose.
  3. If a file (any file in the repo, not just ones with new changes in <branch-name>) didn't get merged properly, edit the files, add them, then run commit --amend to amend that change into the merge commit.

Reminder: No pushing until your files are in the proper state.

On fixing your team's merging strat

We do not have automated tests for our changelog and so I would like to know if it is possible to force developers to manually merge the changelog whenever parallel changes were made (on three-way merge).

Depending on your hosting platform, you can adopt rules, whereby:

  • Developers are not allowed to push non-feature branches (e.g. master). This is sometimes called a "protected branch" in the repo settings.
  • Developers therefore must open a PR in order to get changes into master.

If you team still ends up committing broken CHANGELOG.md, the time might be right to actually develop a CI test for that file so it runs at least for every merge request.

CodePudding user response:

Your changelog syntax makes conflicts impossible to detect without raising endless false positives in other code.

Rather than force changes to work flow, how about changing the log syntax?

Simply adding a '--' line at the end of the unreleased block would do it:

## Unreleased

change X
change Y
--

to

## Unreleased

--

## [1.0.0] - 2023-01-27

change X
change Y

and

## Unreleased

change Z
--

## [1.0.0] - 2023-01-27

change X
change Y

raises a conflict.

CodePudding user response:

When searching for an answer to this I learned that there actually exists a dedicated, custom git merge driver for changelog files called git-merge-changelog. It comes from gnulib, although it is distributed as a separate package (the manual page provided with Fedora had next to no useful information included, the one from Debian was much more useful).

Now for the scenario you describe it did not make any difference when I created a test repository, but the source code is available so maybe you could modify it to be more reluctant to change text after the first line that starts with "## [1?


I am not sure if a custom merge driver is the best tool for this, an alternative could be using git hooks. Now hooks are by default specific for each repo, and not something that is inherited and set up automatically, however there are solutions that makes the hooks version controlled and shared. However the down side regardless is that a fresh clone will need an additional step taken by each developer.


Although it should be noted that this is a bit of an impossible question to decide for a computer because you do not want it to be not possible to make changes like spelling corrections in the text for previous releases. So how do you differentiate between incorrect merge or intentional modifications? One way to do this would be to by default assume incorrect merge and reject, but allow if a specific environment variable is set (e.g. env ALLOW_OLD_CHANGELOG_MODIFICATION=1 git merge some_branch).


1 I am not sure how much the programs assumes about the format of the changelog, if it is very gnu specific or just more or less line based.

  • Related