先前给出的基于钩子的答案将版本字符串的同步与git commit
;紧密结合在一起。但是听起来您希望它以相反的方式工作,即版本是从手动创建的git tag
元数据中提取的。事实证明,实际上这几乎就是git
源代码本身使用的方法,所以让我们通过检查它的方法来了解如何采用类似的方法:
- 它有一个GIT-VERSION-GEN shell 脚本,它试图智能地确定当前版本。本质上,它尝试通过 提取版本字符串
git describe
,但如果这不起作用,则回退到硬编码的默认值。版本被写入GIT-VERSION-FILE
源代码树的顶部。
Makefile
调用此脚本并生成生成的include
文件:
GIT-VERSION-FILE: FORCE
@$(SHELL_PATH) ./GIT-VERSION-GEN
-include GIT-VERSION-FILE
现在该版本可供Makefile
via的其余部分访问$(GIT_VERSION)
。
然后各种 Make 规则使用它对需要硬编码版本字符串的任何文件执行替换,例如各种 Perl 脚本:
$(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 $@+ $@
例如,如果您查看 的开头附近git-svn.perl
,您会看到:
$VERSION = '@@GIT_VERSION@@';
在我的源代码树中,此规则已编译为git-svn
包含以下行的文件:
$VERSION = '1.7.11.rc0.55.gb2478aa';
所以如果我检查本地编译的版本git-svn
,我会看到:
$ git svn --version
git-svn version 1.7.11.rc0.55.gb2478aa (svn 1.6.17)
而如果我运行基于 rpm 的安装,我会看到:
$ /usr/bin/git svn --version
git-svn version 1.7.6.5 (svn 1.6.17)
最后的输出表明,即使源代码是从已发布的 tarball 编译的,该压缩包在.git/
子目录中不包含任何版本控制元数据,该方法仍然有效。这意味着版本字符串可以很好地区分稳定版本和开发快照。
虽然git-svn
是 Perl 脚本,但显然相同的替换方法适用于您的 shell 脚本。