How can I rewrite python __version__ with git?

Another possibility other than Versioneer is setuptools_scm.

I have successfully implemented something very similar to the OP by adding the following to setup.py (or by modifying it accordingly):

from setuptools import setup
setup(
    ...,
    use_scm_version=True,
    setup_requires=['setuptools_scm'],
    ...,
)

and, in order to have __version__ updated automatically, added this to __init__.py of my package:

from pkg_resources import get_distribution, DistributionNotFound
try:
    __version__ = get_distribution(__name__).version
except DistributionNotFound:
    # package is not installed
    pass

It might be better to do this as part of your packaging, rather than after every commit.

There are two primary options:

  • Use git-archive to package, and use the export-subst attribute. Unfortunately, the things you can substitute in are limited to the placeholders from git log --format=.... For example, you could write __version__ = $Format:%H$ in your file, put <filename> export-subst in your .gitattributes, and when you run git archive, that'd be changed to the full hash of the commit you're archiving with. This is just about what you're asking for, but I do prefer the next option.

  • Do it yourself as part of a packaging process (often a build process for compiled packages), and use git describe. That will get you a nice pretty string like v1.7.4.1-59-ge3d3f7d, meaning "59 commits past the tag v1.7.4.1, at commit ge3d3f7d" which you can then insert somehow into the right place in your code as you package/build. This is what Git itself does; the result is dumped to a file, whose contents are read into the makefile and then passed into the build via a -D preprocessor option, and placed into various filenames (e.g. the release tarball) directly.

If you really, really want to do this after every commit, you could, with a post-commit hook, but then only you (and those you give the hook to) will have it, and it's very very possible to get out of sync - you'll also have to have a post-checkout hook, and so on and so on. It's really better for whatever processes that create something needing this version number to get it themselves.

You could also use a smudge/clean filter, which would be more like what you actually want (rather than simply after every commit).

Tags:

Python

Git