1

What is a good way of handling version bumps in git history?

The best approach that I've found so far is something like this:

Version is specified in one of the source files (e.g. Python's __version__)
Do not merge PRs unless the also bump the version
All commits against master must also bump version

I block commits against master, and have git hooks/CI checks that parse the version file and compare it to the existing one. I also have a script that creates a branch and automatically bumps the version as a first commit. One weird side effect is that I have to bump the version even for trivial changes (readme), but having an extra patch version doesn't really hurt so I haven't bothered adding ignores to my version checker, even though it would be easy to do.

Generally, this approach works okay, but is there a better way?

3 Answers 3

3

I would question why you need to specify the version in a file committed to the source repository. You can obtain metadata from the git repository itself. Depending on your release/deployment processes, you can get information from tags, use Conventional Commits or other structured commit messages, or for complicated configurations (perhaps multi-repository projects), using tools to manage versions and states of repositories that correspond to those versions.

4
  • Just to note - it works, but... with this (Conventional Commits + autoincrement of SemVer-compliant version) technique, at least the minor + patch numbering skyrockets very quickly and generates a huge (and disgustingly readable) changelog Nov 12, 2022 at 7:12
  • 1
    @LazyBadger It depends on if you do it on each commit or script the application of a tag. You could look at the last tag and all of the Conventional Commits style commits between the head (or a specified commit) to determine the semantic version based on the types of commits. But if you do it on each commit, then yes, you could end up with absurd increases in version numbers between releases.
    – Thomas Owens
    Nov 12, 2022 at 12:14
  • 3
    @LazyBadger: in my experience, changelogs should be written on a higher level of abstraction than commit messages. They should be structured by released versions, not by each patch level increment, and hence not generated automatically. Commit messages adress developers, changelogs adress the users!
    – Doc Brown
    Nov 12, 2022 at 12:15
  • @DocBrown - definitely "yes", but, as usual "it depends": I cry every time, then I read, f.e., Git's releasenotes. nothing prevents writing (rewriting later) the first line in the "language of the user", and 3+ - in a technically correct language, for internal usage Nov 12, 2022 at 13:32
1

Follow-up on @ThomasOwens:

Maybe "skim" version of Conventional Commits rules (anyway without hardcoded version in file) will be also applicable

  • There is some starting version, fixed in the tag
  • Conventional Commits used in commit-messages
  • CI checks does not autoincrement version on every commit (after all, you can always use git describe for identification)
  • New version calculation used only in "release pipeline", which can
    1. Collapse all "BREAKING CHANGE" after previous release (tagged as "some version MAJOR.MINOR.PATCH") into MAJOR+1
    2. Sum all "feat" after last (chronologically) BREAKING CHANGE into MINOR+X
    3. Sum all "fix" after last (chronologically) feat into PATCH+Y
    4. Tag $THIS changeset with new release version

This way you'll get also

  • semver-compliant
  • autoversioning

but not as reactively incrementing version numbers as "pure" Conventional Commits do in "in wild nature"

0

The most low-maintenance scheme I can think of is

  1. You bump the version when you want to
  2. You use a single, strictly increasing integer, prefixed with something like v (just so that you can use tags for other things if you need to)
#!/usr/bin/env bash

# filename: git-bump
# Bump the version (+1)

latest=$(git tag --list 'v*' --sort=version:refname | sed -e 's/v//' | tail -1)
latest=${latest:0}
next=$((latest + 1))
git tag -a v$next -m$next

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.