有没有办法让 git 自动为 --version 选项生成版本号文件?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33481173/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 11:29:10  来源:igfitidea点击:

Is there a way to make git auto generate a version number file for a --version option?

gitgithubversioncommand-line-argumentsversioning

提问by os x nerd

I have a project that is moving out of the alpha phase and that I'm ready to start releasing regularly. I know GitHub has a 'magic' release button but I generally don't like 'magic' features that I don't know exactly what they do:

我有一个项目正在退出 alpha 阶段,我准备开始定期发布。我知道 GitHub 有一个“魔法”发布按钮,但我通常不喜欢我不知道它们究竟是做什么的“魔法”功能:

https://github.com/blog/1547-release-your-software

https://github.com/blog/1547-release-your-software

As far as I can tell this 'magic' release feature on GitHub just creates a tag on the source repository for a certain state of the code or uses an existing tag. According to that link the tag names must reflect the semantic version number i.e. Major.Minor.Patch ex: v10.1.2 or some thing like that.

据我所知,GitHub 上的这个“神奇”发布功能只是在源存储库上为代码的特定状态创建一个标签或使用现有标签。根据该链接,标签名称必须反映语义版本号,即 Major.Minor.Patch ex: v10.1.2 或类似的东西。

Generally the accepted Git way to do releases seems to be to simply create tags. What I'd like to do is for Git to automatically create some sort of file in my code tree named version.txtor version.hfile that contains the name of the git tag I created so that this file can be automatically sourced when the user issues myporgram --versionon the command line. Preferably I'd like an auto generated header file since this gets integrated into the binary when the program is built. Is there some way to do this automatically or do I have to automatically pipe the tag number into the file before I issue the git tagcommand?

通常,公认的 Git 发布方式似乎是简单地创建标签。我想要做的是让 Git 在我的代码树中自动创建某种文件,名为version.txtversion.h文件,其中包含我创建的 git 标签的名称,以便在用户在命令行上发出myporgram --version。最好我想要一个自动生成的头文件,因为它会在程序构建时集成到二进制文件中。是否有某种方法可以自动执行此操作,或者我是否必须在发出git tag命令之前自动将标签号通过管道传输到文件中?

回答by Igal S.

See nice solution in here: https://coderwall.com/p/mk18zq/automatic-git-version-tagging-for-npm-modules

在这里看到不错的解决方案:https: //coderwall.com/p/mk18zq/automatic-git-version-tagging-for-npm-modules

Basically do it the other way around. Create a text file or header file. Lets say: Version.h:

基本上反过来做。创建文本文件或头文件。让我们说:Version.h:

#define VERSION 10.1.2

And create post-commithook which looks for changes in the file. To deploy: modify the version and commit the file. The hook will create a matching tag.

并创建post-commit用于查找文件更改的钩子。部署:修改版本并提交文件。钩子将创建一个匹配的标签。

回答by Edward

I know this question is old, but I just came across it because I'm trying to do the same thing. The one other answer here shows how to create a new Git tag every time a version file changes, but I and the OP want to do the reverse: Update a code file to contain a new version number every time I create a new Git tag for a "release." Here's how I did it in my C++ project:

我知道这个问题很老,但我刚刚遇到它,因为我正在尝试做同样的事情。这里的另一个答案显示了如何在每次版本文件更改时创建一个新的 Git 标签,但我和 OP 想要做相反的事情:每次我创建一个新的 Git 标签时更新代码文件以包含一个新的版本号一个“释放”。以下是我在 C++ 项目中的做法:

First, create a header file called, for example, include/myproj/git_version.hppthat defines some constants:

首先,创建一个名为的头文件,例如,include/myproj/git_version.hpp它定义了一些常量:

#pragma once
namespace myproject {
extern const int MAJOR_VERSION;
extern const int MINOR_VERSION;
extern const int PATCH_VERSION;
extern const int COMMITS_AHEAD_OF_VERSION;
extern const char* VERSION_STRING;
extern const char* VERSION_STRING_PLUS_COMMITS;
}

Second, create a pre-commithook (.git/hooks/pre-commit) that generates the corresponding .cpp file defining the constants, using the output of git describe:

其次,使用以下输出创建一个预提交钩子 ( .git/hooks/pre-commit),它生成定义常量的相应 .cpp 文件git describe

#!/bin/bash

version_regex='v([0-9]+)\.([0-9]+)\.?([0-9]*)-([0-9]+)-g([0-9|a-z]+)'
git_string=$(git describe --tags --long)

if [[ $git_string =~ $version_regex ]]; then
    major_version="${BASH_REMATCH[1]}"
    minor_version="${BASH_REMATCH[2]}"
    patch_version="${BASH_REMATCH[3]}"
    commits_ahead="${BASH_REMATCH[4]}"
else
    echo "Error: git describe did not output a valid version string. Unable to update git_version.cpp" >&2
    exit 1
fi

version_num="${major_version}.${minor_version}.${patch_version}"
version_num_plus_commits="${version_num}+${commits_ahead}"

# Working directory of a git hook is always the root of the repo
cat > $(pwd)/src/git_version.cpp <<EOM
#include <myproject/git_version.hpp>

namespace myproject {
const int MAJOR_VERSION = $major_version;
const int MINOR_VERSION = $minor_version;
const int PATCH_VERSION = $patch_version;
const int COMMITS_AHEAD_OF_VERSION = $commits_ahead;
const char* VERSION_STRING = "${version_num}";
const char* VERSION_STRING_PLUS_COMMITS = "${version_num_plus_commits}";
}
EOM

git add $(pwd)/src/git_version.cpp

Note that the updated version of the git_constants.cpp file will be included as part of the commit, so any commit based on a new tag will also include a constants file reflecting the version in that tag.

请注意,git_constants.cpp 文件的更新版本将作为提交的一部分包含在内,因此任何基于新标签的提交也将包含一个常量文件,反映该标签中的版本。

This isn't perfect, because it requires you to create a new commit to update the constants file even if all you want to do is create a new tag (which otherwise wouldn't require a new commit). On the other hand, it does allow your in-code version number to track the number of commits, which is more fine-grained than the tagged versions alone.

这并不完美,因为它需要您创建一个新提交来更新常量文件,即使您想做的只是创建一个新标签(否则不需要新提交)。另一方面,它确实允许您的代码版本号跟踪提交的数量,这比单独的标记版本更细粒度。