The hook-based answers previously given tightly couple the synchronization of the version string with a git commit
; however it sounds like you want it to work the other way around, i.e. the version is extracted from manually created git tag
metadata. It turns out that in fact this is pretty much the approach the git
source code itself uses, so let's learn how you could adopt something similar by examining its approach:
- It has a GIT-VERSION-GEN shell script which attempts to intelligently determine the current version. Essentially it tries to extract the version string via
git describe
, but falls back to a hardcoded default if that doesn't work. The version is written to GIT-VERSION-FILE
at the top of the source tree.
The Makefile
invokes this script and include
s the generated file:
GIT-VERSION-FILE: FORCE
@$(SHELL_PATH) ./GIT-VERSION-GEN
-include GIT-VERSION-FILE
Now the version is accessible to the rest of the Makefile
via $(GIT_VERSION)
.
Various Make rules then use this to perform substitutions on any files which need the version string hardcoded, such as various Perl scripts:
$(patsubst %.perl,%,$(SCRIPT_PERL)): % : %.perl GIT-VERSION-FILE
$(QUIET_GEN)$(RM) $@ $@+ && \
INSTLIBDIR=`MAKEFLAGS= $(MAKE) -C perl -s --no-print-directory instlibdir` && \
sed -e '1{' \
[... snipped other substitutions ...]
-e 's/@@GIT_VERSION@@/$(GIT_VERSION)/g' \
$@.perl >$@+ && \
chmod +x $@+ && \
mv $@+ $@
For example if you look near the beginning of git-svn.perl
, you'll see:
$VERSION = '@@GIT_VERSION@@';
In my source tree, this rule has compiled to a file git-svn
which contains the line:
$VERSION = '1.7.11.rc0.55.gb2478aa';
so if I check the version of my locally compiled git-svn
, I see:
$ git svn --version
git-svn version 1.7.11.rc0.55.gb2478aa (svn 1.6.17)
whereas if I run the rpm-based installation, I see:
$ /usr/bin/git svn --version
git-svn version 1.7.6.5 (svn 1.6.17)
This last output demonstrates that the approach works even when the source code is compiled from a released tarball which does not contain any version control metadata in the .git/
subdirectory. This means that the version string nicely distinguishes between stable releases and development snapshots.
Although git-svn
is a Perl script, clearly the same substitution approach would work fine for your shell-script.