Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/git/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
git在同一个提交上使用两个标记进行描述_Git - Fatal编程技术网

git在同一个提交上使用两个标记进行描述

git在同一个提交上使用两个标记进行描述,git,Git,我们偶尔在同一个提交上有两个标记。当我们使用git Descripte进行提交时,git Descripte总是返回第一个标记。我对GitDescripte手册页的阅读似乎表明应该返回第二个标记(这更有意义) 有没有办法让git descripe返回第二个标记?您是否尝试过git descripe的任何选项 --all Instead of using only the annotated tags, use any ref found in .git/refs/. This

我们偶尔在同一个提交上有两个标记。当我们使用git Descripte进行提交时,git Descripte总是返回第一个标记。我对GitDescripte手册页的阅读似乎表明应该返回第二个标记(这更有意义)


有没有办法让git descripe返回第二个标记?

您是否尝试过git descripe的任何选项

   --all
       Instead of using only the annotated tags, use any ref found in .git/refs/. This option enables
       matching any known branch, remote-tracking branch, or lightweight tag.

   --tags
       Instead of using only the annotated tags, use any tag found in .git/refs/tags. This option
       enables matching a lightweight (non-annotated) tag.

据我所知,“git descripe”无法消除轻量级标记的歧义,因此会打印它遇到的第一个标记。此代码段假定标记遵循按“sort-R”排序的模式,并将返回给定SHA上的“latest”标记:

git tag --contains SHA | sort -R | tail -1

Git在本案中的行为既奇怪又令人困惑

当我对同一个提交做两个标记时,我注意到在
.git/refs/tags
中,每个标记都有自己的提交,因此理论上可以以明确的方式签出一个确切的标记

实际上并非如此

让我们假设我已经完成了。我给它做了两个标记(带注释的),v1.0和v2.0

那我就有这样的东西


母版->ABCD
修补程序->ABCD
v1.0(3423)->ABCD
v1.0(4234)->ABCD

当我签出一个分支(如master或hotfix)时,我注意到git只是存储在
.git/HEAD
分支的ref中,所以一切都很好,它不是含糊不清的,而是一个特定的分支

当我直接签出提交时,它本质上是不明确的。HEAD将只包含提交的散列,
ABCD

签出标记(如v1.0或v2.0)时,HEAD将不包含标记ref或标记commit,而是包含commit id,就像您直接签出了commit一样

令人困惑的是,如果您签出一个分支(如master),然后签出一个标记,那么git status和descripe将显示正确的标记,即您签出的标记,即使它不明确

但是,如果您签出另一个指向相同的标记,它将显示原始标记。从分支切换到标记,会记住标记,从标记切换到标记则不会

我不知道这是否是一个bug,也不知道git是如何做到的(我猜它会重复(.git/logs/HEAD),但鉴于这种行为似乎是任意的,我会冒险猜测,如果您只是想使用一个命令来获取用户自上而下选择的内容,无论是标记、分支还是提交,那么我认为这是不可靠的支持

如果您试图使用命令自动获取版本,那么您需要让用户手动输入标记,或者有一些程序来消除冲突

轻量级标记(没有注释,本身没有提交,只是一个指向提交的指针)的行为也很奇怪。考虑到它能够准确地保留用户在一种情况下签出,但在另一种情况下失败的位置,我认为这是一个bug,应该报告

这种情况的使用案例是,用户只签出一个东西,即使该标识符可能指向具有许多其他标识符的东西。为了方便起见,您希望获取用户输入的标识符作为标识符,例如用于构建。Git记住该标识符的能力令人费解地不一致

在这种情况下,您的脚本将需要尝试派生单个最佳标识符,但如果标识符不明确,则会产生错误。您不能依赖git状态或描述,因为有时它们在从一个标记切换到另一个标记而不是从一个标记切换到另一个标记时不会产生上次签出的内容

这可以在
.git/logs/HEAD
中看到,它似乎包含分支到标记的报告,但一旦您在标记上,就不会记录任何内容

description似乎总是返回最新的带注释(非轻量级)标记。如果混合标记类型,则不应假设行为一致。轻量级标记似乎也使用最新版本(可能基于文件的时间戳,而不是提交时间)但是如果没有
--all
--tags
,则无法搜索。即使使用--all,带注释的标记似乎也优先于较新的轻量级标记


获取我能找到的当前标记的所有标识符的唯一方便方法是运行git show ref和取消引用,并对当前提交进行grep。这不包括排序的时间戳。

我在同一个提交上有两个标记约定,希望保留git Descripte的特性,如dirty、sha和commit计数过去的标签等。 因此,在git 2.24.1版中,由于我在一个标记和另一个标记中有一个唯一的区别字符串,所以我只使用了match操作符。您也可以使用exclude


git description--tags--match'*xXx*'

两种方法,具体取决于您的需要

方法1

git tag -l | sort -V | tail -1
git tag --sort=committerdate | tail -1
如果要检查特定格式,例如语义版本

git tag -l | grep "v[0-9]*.[0-9]*.[0-9]*$" | sort -V | tail -1
git tag --sort=committerdate | grep "v[0-9]*.[0-9]*.[0-9]*$" | tail -1
方法2

git tag -l | sort -V | tail -1
git tag --sort=committerdate | tail -1
如果要检查特定格式,例如语义版本

git tag -l | grep "v[0-9]*.[0-9]*.[0-9]*$" | sort -V | tail -1
git tag --sort=committerdate | grep "v[0-9]*.[0-9]*.[0-9]*$" | tail -1

不幸的是,我们已经使用了这些选项。我想知道这是否是一个bug?我只是实际尝试了一下-只要标记被注释,它就会工作-如果我添加一个轻量级标记,它就会被忽略。测试:
$git tag-a test-1-m“just a test”$git descripe test-1$git tag-a test-2-m“另一个测试”$git descripe test-1$git--version git version 1.7.1
-在平局时也会检查标记日期。轻量级标记没有自己的日期信息,因此当它们处于同一提交状态时,不能按日期排序。