在 git 日志中显示所有标记

为什么 git log --decorate每次提交不显示多个标记?

查尔斯 · 贝利(Charles Bailey)已经想出了答案(至少对我来说是这样)
实际上,我有一个指向另一个指向提交的标记。由于这个额外的间接层,标记没有出现在日志中。我将不得不修复这个问题,修复我们的标记脚本以正确地标记,或者通过一些 shell 脚本伏都教递归地跟踪标记。无论如何,我会留下这个问题作为参考,以防有人需要它。(我是堆栈溢出的新手,但我认为这是正确的协议?)

... Original question follows ...

背景: 我们在工作中使用 GIT 进行源代码控制,并且在部署时我们有一个始终标记提交的策略。(它实际上是一个执行标记,然后在服务器上拉标记的脚本)。因为它是一个具有独立的登台服务器和生产服务器的 Web 应用程序,所以我们经常标记一个用于登台的版本(用于测试或其他目的) ,然后标记相同的生产提交。

所以实际上我们经常在同一个提交上有多个标签。如果能在文本日志中看到这一点就太好了,但它似乎并不支持这一点。我目前正在解决这个问题,方法是手动检查我要查找的标记,或者启动 gitk。虽然这两种解决方案都可以工作,但在我看来,git log --decorate在默认情况下只支持每个提交一个标记确实很奇怪。

我谷歌了一下,但没找到什么,我是不是漏掉了什么明显的东西?

P.S. (根据手册页和一些快速测试,我实际上在 %d中使用了一个自定义格式的字符串,它相当于 --decorate)

142808 次浏览

请注意标记的标记(标记标记) ,它是问题的根源,正如 查尔斯 · 贝利在注释中正确指出的:

一定要学习 这根线,因为覆盖一个签名标记并不容易:

  • 如果你已经推了一个标签,git tag man page认真建议不要用简单的 git tag -f B来替换标签名“ A
  • 不要尝试用 git tag -f重新创建带签名的标记(参见下面的线程摘要)

    (它是关于一个角落的例子,但是对于一般的标记是很有指导意义的,它来自另一个 SO 贡献者 Jakub Narębski) :

请注意标记的名称(重量级标记,即标记对象) 储存在两个地方:

  • 在标记对象本身作为‘ tag’头的内容(可以在“ git show <tag>”的输出中看到它,也可以在“ git cat-file -p <tag>”的输出中看到它,其中 <tag>是重量级标记,例如 git.git存储库中的 v1.6.3) ,
  • 也是指向标记对象的标记引用的默认名称(“ refs/tags/*”命名空间中的引用)。
    请注意,标记 参考文献(在“ refs/tags/*”名称空间中的适当引用)是纯粹的 本地事项; 例如,一个存储库在‘ refs/tags/v0.1.3’中具有什么,其他存储库在‘ refs/tags/sub/v0.1.3’中具有什么。

因此,当您创建带有符号的标记‘ A’时,会出现以下情况(假设它指向某个提交)

  35805ce   <--- 5b7b4ead  <=== refs/tags/A
(commit)       tag A
(tag)

还请注意,“ git tag -f A A”(注意没有强制它成为带注释标记的选项)是 noop-它不会改变这种情况。

如果你使用“ git tag -f -s A A”: 注意你的 力量写了一个标签(所以 git 假设你知道你在做什么) ,并且使用了 -s/-a/-m选项之一来强制使用带注释的标签(创建标签对象) ,你会得到下面的情况

  35805ce   <--- 5b7b4ea  <--- ada8ddc  <=== refs/tags/A
(commit)       tag A         tag A
(tag)         (tag)

Note also that "git show A" would show the whole chain down to the non-tag object...

注意: 卡尔森(bk2204)中的 第五季,第13集,完(针对 git 1.9/2.0 Q12014)处理了一种特殊的带标签的原木装饰:

用链式标签正确处理装饰物

当一个标记对象引用另一个不再是引用的标记对象时,比如当第二个标记被删除 时,git log没有正确处理修饰。
提交不会被正确修饰,因为没有对第二个标记调用 parse_object,因此它的标记字段没有被填充,导致没有任何标记与相关的提交相关联。

如果该字段不存在,则调用 parse_object来填充该字段,以便标记链可以被解引用,并且提交可以得到适当的修饰。
也包括测试,以防止未来的回归。

例如:

git tag -a tag1 -m tag1 &&
git tag -a tag2 -m tag2 tag1 &&
git tag -d tag1 &&
git commit --amend -m shorter &&
git log --no-walk --tags --pretty="%H %d" --decorate=full
git log --no-walk --tags --pretty="%h %d %s" --decorate=full

这个版本也会打印提交消息:

 $ git log --no-walk --tags --pretty="%h %d %s" --decorate=full
3713f3f  (tag: refs/tags/1.0.0, tag: refs/tags/0.6.0, refs/remotes/origin/master, refs/heads/master) SP-144/ISP-177: Updating the package.json with 0.6.0 version and the README.md.
00a3762  (tag: refs/tags/0.5.0) ISP-144/ISP-205: Update logger to save files with optional port number if defined/passed: Version 0.5.0
d8db998  (tag: refs/tags/0.4.2) ISP-141/ISP-184/ISP-187: Fixing the bug when loading the app with Gulp and Grunt for 0.4.2
3652484  (tag: refs/tags/0.4.1) ISP-141/ISP-184: Missing the package.json and README.md updates with the 0.4.1 version
c55eee7  (tag: refs/tags/0.4.0) ISP-141/ISP-184/ISP-187: Updating the README.md file with the latest 1.3.0 version.
6963d0b  (tag: refs/tags/0.3.0) ISP-141/ISP-184: Add support for custom serializers: README update
4afdbbe  (tag: refs/tags/0.2.0) ISP-141/ISP-143/ISP-144: Fixing a bug with the creation of the logs
e1513f1  (tag: refs/tags/0.1.0) ISP-141/ISP-143: Betterr refactoring of the Loggers, no dependencies, self-configuration for missing settings.

注: 我只是在回答问题的 主题:

在 git 日志中显示所有标记

问题的具体细节。

为每个标记的提交显示完整的 git log(颜色!) :

我真的认为这是最有用和最美丽的形式:

git log --no-walk --tags

它显示了每个提交的完整 git log输出,其中有一个附加的标记。非常方便!

如果你只想过滤出符合特定字符串搜索模式的标签,可以这样做:

git log --no-walk --tags=*some_string*

Example:

git log --no-walk --tags=*release/my_board*

为每个标记的提交显示一行 git log摘要(颜色!) :

If you'd like to just see one line per tagged commit, do this instead. Note: this is modified from Coderwall's beautiful git lg alias:

git log --color --no-walk --tags --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

当然,你仍然可以使用 --tags=*some_string*表单过滤特定的标签:

git log --color --no-walk --tags=*some_string* --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

例如:

git log --color --no-walk --tags=*release/my_board* --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit

参考文献:

  1. 作者:@Marcello de Sales帮助我开始。
  2. Coderwall 美丽的 git lg化名