如何在git中显示标签的完整历史记录?

6

据说,Git 中的标签可以通过删除和重新打标签来移动到另一个提交中。

例如:

git tag -m "Version 1.0" v1.0 abcd123
git push --tags
git tag -d v1.0
git tag -m "Corrected version 1.0" v1.0 1234abc
git push --tags

如何查看特定标签的完整历史记录?(换句话说,任何该名称的标签何时被创建/删除以及每个标签指向哪些提交)

如何查看所有标签的完整历史记录?

1个回答

10

它们也可以被强制移动:

git tag -f ...

然后强制推送。

如何查看特定标签的完整历史记录?(换句话说,任何时候创建/删除该名称标签以及每个标签指向的提交)

一般来说,你不能。

如果标签被强制移动和强制推送,并且您保留了标签的 reflog,则可以从标签的 reflog 中检索先前的值,直到这些 reflog 条目过期。但是,删除引用(任何引用)会删除 reflog。

注释标签使用存储在仓库中的对象(除了引用本身)。删除引用仅删除对注释标签对象的外部标签名称引用。只要底层对象本身没有被删除,就可以通过 ID 访问它。但是,作为未引用的对象,它受到通常的垃圾回收规则的约束。只有某些附加引用(通常是另一个注释标签的另一个标签名称)使原始注释标签对象可访问,才能保证其保留在仓库中。

(树对象无法指向标记对象,因此可能会有一个提交对象指向保留旧注释标记的树。但是 Git 没有构建这样的功能,并且没有用于构建此类内容的工具,而且可能会导致 git fsck 认为它们是错误的。因此,这更多是一种理论练习:通过特殊提交(通常通过新的引用名称空间(例如 refs/tagarchive/)指向),可以在至少编写一个 Git 管道命令和几个脚本的情况下保存和持久化“旧标签”和“标签历史记录”。当然,在有人编写这些之前,这都是纯粹的猜测。也不清楚它们将如何有用。)


这是一个很好的答案,但我不确定如何应用它;我对git的一些内部机制不够熟悉。 “只要底层对象本身没有被删除,您就可以通过ID访问它” - 我该如何列出未引用的对象?我该如何知道它们中哪些是标签?我该如何知道每个标签是哪一个? - Alex I
1
“它们的用处并不明显。”对我来说,标签常用于标记发布版本,似乎非常有价值。就像无法在修改历史记录中更改代码一样(好吧,有点可以 - 我知道强制推送更改),应该无法更改标签而不记录,可能还要在修改历史记录中记录。如果这个功能确实不存在,那么我会开始使用提交信息来标记发布版本,因为它们很难在没有记录的情况下进行修改,或者除了标签之外也会使用提交消息来标记发布版本。 - Alex I
git fsck(https://www.kernel.org/pub/software/scm/git/docs/git-fsck.html)可以查找未引用的对象,包括标签。另请参见https://dev59.com/3loV5IYBdhLWcg3wJ8Ab。关于有用性:您不应该永远更改或删除标签。这就是标签的目的所在。请参见https://www.kernel.org/pub/software/scm/git/docs/git-tag.html#_on_re_tagging了解Linus Torvald对此的看法。 - torek
@torek,没错。除非活跃的克隆少于一把手,否则更新标签是一个混乱的问题。我认为这更好地被构建为一个访问控制问题。换句话说,如果人们在没有考虑的情况下更新标签,则应该使用“pre-receive”钩子拒绝修改和删除标签。 - Chris
1
@torek 不应该这样做,哈哈,但如果有人这样做了呢?垃圾回收后甚至不会有任何记录。 - Alex I
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接