如何维护受git源控制的bash脚本的版本号?

hel*_*hod 14 git bash version

我刚刚完成了一个更复杂的bash脚本的第一个工作版本,我正在围绕如何维护脚本版本.

我为什么需要这个?遵循命令行界面的GNU编码标准我添加了一个版本选项,在许可证和版权标题中显示当前版本.

不过,我不知道如何让版本"保持最新".

到目前为止,我的想法是使用git标签作为主要的| 未成年人 补丁发布,并以某种方式替换脚本中包含的变量.

所以,如果我有一个名为的标签1.1.0,那么

$ myscript --version
Run Code Online (Sandbox Code Playgroud)

应输出如下内容:

myscript 1.1.0
Run Code Online (Sandbox Code Playgroud)

该脚本包含一个shell变量:

version=1.1.0
Run Code Online (Sandbox Code Playgroud)

不过,我现在不知道如何使版本与最新标签保持同步?

小智 12

据我所知,你想要的是不可能的.为了将版本号提交到版本控制软件中,您必须编辑版本号,提交,然后标记; 而不是相反.但是,您可以使流程更加简化.

我们可以通过编写一个post-commit钩子来读取你的脚本的版本号,如果它从上次改变了,就写出一个新的标签.为了做到这一点,.git/hooks从你的项目目录进入cd ,创建一个名为post-commit(或移动post-commit.sample)的文件并使其可执行.然后编辑它,使它看起来像这样:

#!/bin/bash

NEWEST_TAG=$(git describe --abbrev=0 --tags)

SCRIPT_VERSION=$(grep "^version=" myscript | awk -F= '{print $2}')

if [ x$NEWEST_TAG != x$SCRIPT_VERSION ]; then
    git tag -a $SCRIPT_VERSION -m "version $SCRIPT_VERSION"
fi
Run Code Online (Sandbox Code Playgroud)

下次碰到脚本的版本号并提交更改时,您会看到新标记添加到最新提交中.


Ada*_*ers 7

先前给出的基于钩子的答案将版本字符串的同步与a紧密耦合git commit; 但是听起来你希望它以相反的方式工作,即从手动创建的git tag元数据中提取版本.事实证明,事实上这几乎就是git源代码本身使用的方法,所以让我们通过检查它的方法来学习如何采用类似的东西:

  • 它有一个GIT-VERSION-GEN shell脚本,它试图智能地确定当前版本.本质上它试图通过提取版本字符串git describe,但如果不起作用则回退到硬编码默认值.该版本将写入GIT-VERSION-FILE源树的顶部.
  • Makefile调用此脚本和includeS中生成的文件:

    GIT-VERSION-FILE: FORCE
            @$(SHELL_PATH) ./GIT-VERSION-GEN
    -include GIT-VERSION-FILE
    
    Run Code Online (Sandbox Code Playgroud)

    现在的版本是将其余访问Makefile通过$(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 $@+ $@
    
    Run Code Online (Sandbox Code Playgroud)

    例如,如果你看起来接近开头git-svn.perl,你会看到:

    $VERSION = '@@GIT_VERSION@@';
    
    Run Code Online (Sandbox Code Playgroud)

在我的源代码树中,此规则已编译为git-svn包含以下行的文件:

    $VERSION = '1.7.11.rc0.55.gb2478aa';
Run Code Online (Sandbox Code Playgroud)

所以,如果我检查我本地编译的版本git-svn,我看到:

    $ git svn --version
    git-svn version 1.7.11.rc0.55.gb2478aa (svn 1.6.17)
Run Code Online (Sandbox Code Playgroud)

而如果我运行基于rpm的安装,我会看到:

    $ /usr/bin/git svn --version
    git-svn version 1.7.6.5 (svn 1.6.17)
Run Code Online (Sandbox Code Playgroud)

最后一个输出表明,即使源代码是从已发布的tarball编译而来的,该方法仍然有效,该tarball在.git/子目录中不包含任何版本控制元数据.这意味着版本字符串可以很好地区分稳定版本和开发快照.

虽然git-svn是一个Perl脚本,显然相同的替换方法可以适用于您的shell脚本.