git git中如何使用标签来管理软件版本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3929975/
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-10 09:17:15  来源:igfitidea点击:

How do you use tags in git to manage software versions

gittags

提问by Frank M

We use git to manage our project, we have a branch for each: dev staging production

我们使用 git 来管理我们的项目,我们有一个分支:dev staging production

I want to use git tags to manage versions of the software. As far as I can see if I am on a branch and add a few commits, I then have to run: git tag 1.0

我想使用 git 标签来管理软件的版本。据我所知,如果我在一个分支上并添加了一些提交,那么我必须运行:git tag 1.0

Repacing 1.0 with whatever version number we are up to, then I can push the tag using: git push origin 1.0

用我们要达到的任何版本号重新调整 1.0,然后我可以使用以下方法推送标签: git push origin 1.0

And I can update the branch with: git push --tags

我可以使用以下命令更新分支: git push --tags

But how do I reuse a tag now? If I commit more code to my local repository and want it to be version 1.0 easily? Or do you just add a new tag like 1.1?

但是我现在如何重用标签?如果我向本地存储库提交更多代码并希望它轻松成为 1.0 版?或者你只是添加一个像 1.1 这样的新标签?

Also, what happens if my colleague uses the same tag name on his local repository and we both push the code for that same tag up?

另外,如果我的同事在他的本地存储库中使用相同的标签名称,而我们都将相同标签的代码向上推送,会发生什么?

Lastly, what happens if we accidentally push our code without running git tag to tag the commits.

最后,如果我们不小心推送我们的代码而没有运行 git tag 来标记提交会发生什么。

I'm not really getting how tags work, I thought they would work like you would tag a blog post or something - you can tag lots of different commits with the same tag and reuse the tag etc. kind of like a branch I guess.

我并没有真正了解标签是如何工作的,我认为它们会像标记博客文章或其他东西一样工作 - 您可以使用相同的标签标记许多不同的提交并重用标签等。我猜有点像分支。

回答by Jonathan

But how do I reuse a tag now? If I commit more code to my local repository and want it to be version 1.0 easily? Or do you just add a new tag like 1.1?

但是我现在如何重用标签?如果我向本地存储库提交更多代码并希望它轻松成为 1.0 版?或者你只是添加一个像 1.1 这样的新标签?

You can delete the tag with git tag -d 1.0, then delete it on the server with git push origin :refs/tags/1.0.

您可以使用 删除标签git tag -d 1.0,然后在服务器上使用 删除它git push origin :refs/tags/1.0

But the best practice is to only tag releases, and then create a maintenance branch for that release at the point where the tag is created. On that branch you push your fixes, and tag with 1.1, 1.2, ... as you make updated releases. It is bad practice to move a tag after you've given that code to a customer.

但最佳实践是只标记版本,然后在创建标记的位置为该版本创建维护分支。在该分支上,您推送您的修复程序,并在您发布更新版本时标记 1.1、1.2、...。在将代码提供给客户后移动标签是不好的做法。

Also, what happens if my colleague uses the same tag name on his local repository and we both push the code for that same tag up?

另外,如果我的同事在他的本地存储库中使用相同的标签名称,而我们都将相同标签的代码向上推送,会发生什么?

I'm pretty sure the second one of you to push the tag will receive an error. Try it yourself to see what happens:

我很确定你们中的第二个推送标签会收到错误。自己试试看会发生什么:

git checkout -b testbranch
git tag test1
git push origin tag test1
git tag -d test1
touch testfile
git add testfile
git commit -m "Added testfile"
git push origin testbranch
git tag test1
git push origin tag test1

Lastly, what happens if we accidentally push our code without running git tag to tag the commits.

最后,如果我们不小心推送我们的代码而没有运行 git tag 来标记提交会发生什么。

You should push your tags after you've pushed the commits. You cannot do both at the same time (git push --tagsdoes not push commits, only tags). If you push tags first, the remote will have dangling references until you push the commits. So you should be doing

您应该在推送提交后推送您的标签。您不能同时执行这两项操作(git push --tags不推送提交,只推送标签)。如果您先推送标签,远程将有悬空引用,直到您推送提交。所以你应该做

git push origin master
git push origin --tags

or similar, depending on your situation.

或类似,取决于您的情况。

I'm not really getting how tags work, I thought they would work like you would tag a blog post or something - you can tag lots of different commits with the same tag and reuse the tag etc. kind of like a branch I guess.

我并没有真正了解标签是如何工作的,我认为它们会像标记博客文章或其他东西一样工作 - 您可以使用相同的标签标记许多不同的提交并重用标签等。我猜有点像分支。

Tags are like labels on commits, so you can mark some commits as being 'special'. Most commonly, this is used to tag releases, so you can always go back and see exactly what was in that release if a customer reports a bug.

标签就像提交上的标签,因此您可以将某些提交标记为“特殊”。最常见的是,这用于标记版本,因此如果客户报告错误,您可以随时返回并查看该版本中的确切内容。

回答by yano

Simply answering the title question, I've come up with a semi-professional solution (that may be of use to some people) that automatically tags my code with the git version tag I'm pointing to so I don't have to (remember to) manually update a version number each time I build. I currently work in a small group (< 5 developers), and our configuration management is still a work in progress. But until that matures, this is a solution that works for me.

简单地回答标题问题,我想出了一个半专业的解决方案(可能对某些人有用),它会自动用我指向的 git 版本标签标记我的代码,所以我不必(记得)每次构建时手动更新版本号。我目前在一个小组(< 5 个开发人员)工作,我们的配置管理仍在进行中。但在成熟之前,这是一个对我有用的解决方案。

High level view, these are the steps:

高级视图,这些是步骤:

  • I wrote a script that queries git for my current version tag (using the beginning parts of this answer).

  • Auto-generate a header file that #defines the extracted version and its parts.

  • Put a shell command early on in my top-level makefile that runs this script (so the header file is generated every time I build something).
  • Relevant code #includes this header file (which is notpart of the repository), and voila, the version is automatically included without any manual input from me.
  • 我写了一个脚本来查询 git 以获得我当前的版本标签(使用这个答案的开头部分)。

  • 自动生成包含#define提取版本及其部分的头文件。

  • 在运行此脚本的顶级 makefile 中尽早放置一个 shell 命令(因此每次构建时都会生成头文件)。
  • 相关代码#include是这个头文件(它不是存储库的一部分),瞧,该版本会自动包含在内,无需我手动输入。

In more detail:

更详细地:

The Script

剧本

I currently use a 3 number versioning scheme,, major.minor.build, where buildcan possibly be a string (for example, v1.8.3b). Note, that using echo -eto print newlines works for me, but perhaps printfis the better option

我目前使用 3 个数字版本控制方案,major.minor.build,其中build可能是一个字符串(例如,v1.8.3b)。请注意,使用echo -e打印换行符对我有用,但也许printf是更好的选择

# queries git for the version tag I'm currently pointed at. Throughout SO there
# are different versions of this command, but this one works for me. And in fact
# all my tags are annotated, so I could just use "git describe"
VERSION=`git describe --tags`

# replace all the '.' with ' ', then split the array based on the spaces.
# Obviously this will have its limitations if there are spaces in your
# version tag, or maybe even wildcard characters, but that should never
# be the case for me
VER_ARRAY=(${VERSION//./ })
# pull out the major, minor, and build components. These can be used to
# pre-processor check different versions of my code for certain compatibility,
# should the need arise
V_MAJOR=${VER_ARRAY[0]}
V_MINOR=$(VER_ARRAY[1]}
V_BUILD=${VER_ARRAY[2]}

# all of my build tags are preceded by a 'v', so remove that simply by taking
# the substring starting at position 1
V_MAJOR=${V_MAJOR:1}

# define the path and header file
VERSION_HEADER=./path/to/codeVer.h

# write these to file. > creates the file and >> appends to the file
echo -e "// Auto-generated version header on " `date` "\n\n" > $VERSION_HEADER
echo -e "#define MY_CODE_VERSION \""$VERSION"\"\n\n" >> $VERSION_HEADER
echo -e "#define MY_CODE_MAJOR "$V_MAJOR >> $VERSION_HEADER
echo -e "#define MY_CODE_MINOR "$V_MINOR >> $VERSION_HEADER
echo -e "#define MY_CODE_BUILD \""$V_BUILD"\"\n\n" >> $VERSION_HEADER

The makefile

生成文件

At the top of my makefile, I have $(shell ./genVer.sh). This tells make to run a shell command, ./genVer.shis the path and name of the script. A better way to do this would be to make a .PHONYtarget for the script, and then put that target as a prerequisite for the pertinent targets,, but I have a lot of targets and this was a one-liner catch all.

在我的 makefile 的顶部,我有$(shell ./genVer.sh). 这告诉 make 运行一个 shell 命令,./genVer.sh是脚本的路径和名称。更好的方法是.PHONY为脚本制定一个目标,然后将该目标作为相关目标的先决条件,但我有很多目标,这是一个单线包罗万象的方法。

The code

编码

Now, in all relevant source/header files, I simply have

现在,在所有相关的源/头文件中,我只有

#include "codeVer.h"
....
#ifndef MY_CODE_VERSION
  // although if codeVer.h cannot be found we will get a fatal error before
  // this warning
  #warning "Unable to find code version, defaulting to v0.0.0"
  #define MY_CODE_VERSION "v0.0.0"
#endif

Now any time I make, the current version is extracted, the header is generated, my code #includes the file, and I get the correct version number without doing any manual work. Note, this doesn't just work for the latest version, if you checkout an older tag, this will work as well (provided of course the changes implementing this were in that version).

现在任何时候我make都会提取当前版本,生成标题,我的代码#include是文件,并且无需任何手动工作即可获得正确的版本号。请注意,这不仅适用于最新版本,如果您签出较旧的标签,这也适用(当然,前提是实现此功能的更改在该版本中)。

This does have its drawbacks. Most notably

这确实有其缺点。最为显着地

  1. You have to build somethingin order to get the version. I actually added codeVer.hto the .gitignore list since I don't want it tracked in the repo. This means you could potentially hand your code off to someone with this file missing, and they won't know what version it is. But if they're using git (like they're supposed to be doing!) and they git pull/cloneyour stuff, all the tags will come with it anyway.
  2. make cleanalso generates this file (which seems counter-intuitive), but if you did it the right way and used a .PHONYtarget as described above, that wouldn't be an issue.
  3. Probably others I'm not thinking about at the moment.
  1. 您必须构建一些东西才能获得版本。我实际上添加codeVer.h到 .gitignore 列表中,因为我不希望它在 repo 中被跟踪。这意味着您可能会将您的代码交给丢失此文件的人,而他们将不知道它是什么版本。但是,如果他们使用 git(就像他们应该做的那样!)并且他们使用git pull/clone您的东西,那么无论如何所有标签都会随之而来。
  2. make clean还会生成此文件(这似乎违反直觉),但是如果您以正确的方式进行操作并使用.PHONY如上所述的目标,那将不是问题。
  3. 可能其他人我现在没有考虑。

回答by cmcginty

A great resource for tag info is on gitref.org

gitref.org上有一个很好的标签信息资源

Don't try and reuse version numbers. Best is to just go to 1.1 or 1.0a. This is discussed at length in the man page.

不要尝试重复使用版本号。最好是去 1.1 或 1.0a。这在手册页中有详细讨论。

For your question:

对于您的问题:

Lastly, what happens if we accidentally push our code without running git tag to tag the commits?

最后,如果我们不小心推送我们的代码而没有运行 git tag 来标记提交,会发生什么?

You can tag old commits by putting the commit ref in the command:

您可以通过将提交引用放在命令中来标记旧提交:

git tag 1.1 HEAD~3