git describe 什么时候以及为什么不显示最新标签?
When and why exactly does git describe not show the latest tag?
我有三个分支:dev
、staging
和 master
。当我执行 git describe
结果是 v0.1
无论签出哪个分支。
下面我将描述更改为 dev
添加版本标记并合并到 staging
和 master
这个新版本的工作流程。
git checkout dev
- 做一些改变
git add --all
&& git commit -m 'just some testing'
git tag -a v0.19.0
git push && git push --tags
git checkout staging
git merge dev
git push
git checkout master
git merge staging
git push
现在我 运行 describe
在每个分支上:
- git checkout dev && git describe && git describe --abbrev=0
结果:
v0.19.0-1-ge147b2d
v0.19.0
我的预期:
v0.19.0-1-ge147b2d
v0.19.0
git checkout staging && git describe && git describe --abbrev=0
结果:
v0.17.0-3-g684216f
v0.17.0
我的预期:
v0.19.0-xxxxx
v0.19.0
git checkout master && git describe && git describe --abbrev=0
结果:
v0.17.0-16-g99c19c9
v0.17.0
我的预期:
v0.19.0-xxxxx
v0.19.0
这是为什么?我怎样才能有这样一个过程,我在 dev 中进行一些更改,然后添加一个新标签,然后将带有标签的这些更改传播到所有其他分支?
你应该写下所有命令你实际上运行而不是尝试使用英语,因为它似乎不能足够准确地解释情况。例如,您的措辞使用“merge into”和“merge to”,这对您来说可能描述也可能不同。对于合并,您通常会执行类似 git checkout some-local-branch && git fetch && git merge origin/some-other-branch
的操作。如果您自己不能确定了解整个情况,那么所有细节可能都很重要。如果你 运行 一些命令,例如通过 ssh 连接的远程机器,一定要指出这一点。
从问题(措辞为 2021-04-27T14:24:13+00:00)来看,您的流程 2 似乎缺失 git push --tags
(或者可能 git fetch
),如果您尝试 运行 git describe
其他地方 但原始存储库(即您的工作目录)您根本看不到新标签。
我建议在您尝试使用的所有工作区(或“分支”)中从 git show NEWTAG
开始。您应该在每个工作区获得相同的 SHA-1。您还可以 运行 git show HEAD
来验证当前 HEAD 是否确实匹配您认为应该匹配的内容。此外,如果你可以 运行 gitk
你可以尝试 运行ning gitk NEWTAG HEAD
来获得问题的视觉表示,甚至 gitk --all -n 10000
来显示所有分支到 10000最新提交。
如果你不能使用gitk
,你也可以试试运行ning,例如git log --oneline --graph --decorate -n 50
。作为替代方案,您还可以 运行 git log --oneline --graph --decorate -n 50 --format=%h%d
列出 DAG 中最新的 50 次没有标题的提交,以便在需要更多帮助时可以在 SO 中共享结果。
看到截图更新
您的分支 master
与您的任何标签不在同一位置,因此 git describe
不应将任何给定的标签名称作为唯一输出。相反,它应该说类似 v0.2-4-gf5d6ced
的内容,这基本上意味着“v0.2 加上 4 个补丁,HEAD 指向以 f5d6ced
开头的 SHA-1”。此示例的四个补丁程序是 a5312dc、7dceb15、b4cd4f6 和 f5d6ced,它们 未包含在下面的 v0.2
中。
这是我创建的示例:
* f5d6ced (HEAD -> master) Merge branch 'staging'
|\
| * b4cd4f6 (staging) Merge branch 'dev' into staging
| |\
| | * 1fa7a37 (tag: v0.2, dev) Updated testfile yet again in branch dev
* | | 7dceb15 (tag: test) Merge branch 'staging'
|\ \ \
| |/ /
| * | a5312dc Merge branch 'dev' into staging
| |\ \
|/ / /
| | _
| * 96cd0ac (tag: v0.1) Updated testfile in branch dev
|/
* d626941 Added testfile in branch dev
v0.1
和 v0.2
是带注释的标签,test
是 non-annotated 标签。
$ git checkout dev && git describe
Switched to branch 'dev'
v0.2
$ git checkout staging && git describe
Switched to branch 'staging'
v0.2-2-gb4cd4f6
$ git checkout master && git describe
Switched to branch 'master'
v0.2-4-gf5d6ced
$ git checkout master && git describe --tags
Already on 'master'
test-3-gf5d6ced
这是因为当您创建合并时,您创建了一个新的提交,它显然会有自己的 SHA-1 标识符,并且现有标签不指向合并,因为标签总是引用特定版本.
你确定你不是 运行宁例如git describe --abbrev=0
它只从最近的标签中选择一个标签,并且可能更喜欢第一个 parent 用于任何给定的合并?
如果你真的想弄清楚你给定的分支已经包含了哪些标签,你可以运行像这样:
$ git checkout master && git tag --merged
Switched to branch 'master'
test
v0.1
v0.2
或按标签创建时间排序,最新的在前:
$ git checkout master && git tag --sort=-authordate --merged
Already on 'master'
test
v0.2
v0.1
如果你想要只是最新的标签,你可以运行
git tag --list --sort=-authordate --merged | head -n1
有关详细信息,请参阅 git help tag
。对于这种情况,latest 表示给定标签的 authoring timestamp。对于标签,作者时间戳和提交时间戳是相等的,但据我所知,这并没有在任何地方强制执行。如果差异对您很重要,只有您自己决定需要哪个时间戳。
对您的特定“错误”案例的进一步解释:您实际上并没有像您声称的那样运行git describe
,而是git describe --abbrev=0
列出 最近的 标记。请注意,这是在 DAG 拓扑中,它可能与 latest 或 newest 标签完全不同。对于您的示例,v0.17
和 v0.19
与分支 staging
的 HEAD
的距离为 1,与 master
的 HEAD
的距离为 2。此外,较旧的标签来自第一个 parent,这就是为什么您得到 v0.17
作为响应的原因。如果您想要给定分支中包含的最新标签,我建议您改用 git tag --list --sort=-authordate --merged | head -n1
。但是,我强烈建议标记主分支版本,而不是在开发或暂存分支中标记随机补丁。然后你可以只使用 git describe
没有任何标志
我有三个分支:dev
、staging
和 master
。当我执行 git describe
结果是 v0.1
无论签出哪个分支。
下面我将描述更改为 dev
添加版本标记并合并到 staging
和 master
这个新版本的工作流程。
git checkout dev
- 做一些改变
git add --all
&&git commit -m 'just some testing'
git tag -a v0.19.0
git push && git push --tags
git checkout staging
git merge dev
git push
git checkout master
git merge staging
git push
现在我 运行 describe
在每个分支上:
- git checkout dev && git describe && git describe --abbrev=0
结果:
v0.19.0-1-ge147b2d
v0.19.0
我的预期:
v0.19.0-1-ge147b2d
v0.19.0
git checkout staging && git describe && git describe --abbrev=0
结果:
v0.17.0-3-g684216f
v0.17.0
我的预期:
v0.19.0-xxxxx
v0.19.0
git checkout master && git describe && git describe --abbrev=0
结果:
v0.17.0-16-g99c19c9
v0.17.0
我的预期:
v0.19.0-xxxxx
v0.19.0
这是为什么?我怎样才能有这样一个过程,我在 dev 中进行一些更改,然后添加一个新标签,然后将带有标签的这些更改传播到所有其他分支?
你应该写下所有命令你实际上运行而不是尝试使用英语,因为它似乎不能足够准确地解释情况。例如,您的措辞使用“merge into”和“merge to”,这对您来说可能描述也可能不同。对于合并,您通常会执行类似 git checkout some-local-branch && git fetch && git merge origin/some-other-branch
的操作。如果您自己不能确定了解整个情况,那么所有细节可能都很重要。如果你 运行 一些命令,例如通过 ssh 连接的远程机器,一定要指出这一点。
从问题(措辞为 2021-04-27T14:24:13+00:00)来看,您的流程 2 似乎缺失 git push --tags
(或者可能 git fetch
),如果您尝试 运行 git describe
其他地方 但原始存储库(即您的工作目录)您根本看不到新标签。
我建议在您尝试使用的所有工作区(或“分支”)中从 git show NEWTAG
开始。您应该在每个工作区获得相同的 SHA-1。您还可以 运行 git show HEAD
来验证当前 HEAD 是否确实匹配您认为应该匹配的内容。此外,如果你可以 运行 gitk
你可以尝试 运行ning gitk NEWTAG HEAD
来获得问题的视觉表示,甚至 gitk --all -n 10000
来显示所有分支到 10000最新提交。
如果你不能使用gitk
,你也可以试试运行ning,例如git log --oneline --graph --decorate -n 50
。作为替代方案,您还可以 运行 git log --oneline --graph --decorate -n 50 --format=%h%d
列出 DAG 中最新的 50 次没有标题的提交,以便在需要更多帮助时可以在 SO 中共享结果。
看到截图更新
您的分支 master
与您的任何标签不在同一位置,因此 git describe
不应将任何给定的标签名称作为唯一输出。相反,它应该说类似 v0.2-4-gf5d6ced
的内容,这基本上意味着“v0.2 加上 4 个补丁,HEAD 指向以 f5d6ced
开头的 SHA-1”。此示例的四个补丁程序是 a5312dc、7dceb15、b4cd4f6 和 f5d6ced,它们 未包含在下面的 v0.2
中。
这是我创建的示例:
* f5d6ced (HEAD -> master) Merge branch 'staging'
|\
| * b4cd4f6 (staging) Merge branch 'dev' into staging
| |\
| | * 1fa7a37 (tag: v0.2, dev) Updated testfile yet again in branch dev
* | | 7dceb15 (tag: test) Merge branch 'staging'
|\ \ \
| |/ /
| * | a5312dc Merge branch 'dev' into staging
| |\ \
|/ / /
| | _
| * 96cd0ac (tag: v0.1) Updated testfile in branch dev
|/
* d626941 Added testfile in branch dev
v0.1
和 v0.2
是带注释的标签,test
是 non-annotated 标签。
$ git checkout dev && git describe
Switched to branch 'dev'
v0.2
$ git checkout staging && git describe
Switched to branch 'staging'
v0.2-2-gb4cd4f6
$ git checkout master && git describe
Switched to branch 'master'
v0.2-4-gf5d6ced
$ git checkout master && git describe --tags
Already on 'master'
test-3-gf5d6ced
这是因为当您创建合并时,您创建了一个新的提交,它显然会有自己的 SHA-1 标识符,并且现有标签不指向合并,因为标签总是引用特定版本.
你确定你不是 运行宁例如git describe --abbrev=0
它只从最近的标签中选择一个标签,并且可能更喜欢第一个 parent 用于任何给定的合并?
如果你真的想弄清楚你给定的分支已经包含了哪些标签,你可以运行像这样:
$ git checkout master && git tag --merged
Switched to branch 'master'
test
v0.1
v0.2
或按标签创建时间排序,最新的在前:
$ git checkout master && git tag --sort=-authordate --merged
Already on 'master'
test
v0.2
v0.1
如果你想要只是最新的标签,你可以运行
git tag --list --sort=-authordate --merged | head -n1
有关详细信息,请参阅 git help tag
。对于这种情况,latest 表示给定标签的 authoring timestamp。对于标签,作者时间戳和提交时间戳是相等的,但据我所知,这并没有在任何地方强制执行。如果差异对您很重要,只有您自己决定需要哪个时间戳。
对您的特定“错误”案例的进一步解释:您实际上并没有像您声称的那样运行git describe
,而是git describe --abbrev=0
列出 最近的 标记。请注意,这是在 DAG 拓扑中,它可能与 latest 或 newest 标签完全不同。对于您的示例,v0.17
和 v0.19
与分支 staging
的 HEAD
的距离为 1,与 master
的 HEAD
的距离为 2。此外,较旧的标签来自第一个 parent,这就是为什么您得到 v0.17
作为响应的原因。如果您想要给定分支中包含的最新标签,我建议您改用 git tag --list --sort=-authordate --merged | head -n1
。但是,我强烈建议标记主分支版本,而不是在开发或暂存分支中标记随机补丁。然后你可以只使用 git describe
没有任何标志