Git标记指向未出现在日志中的提交

时间:2017-03-01 11:20:12

标签: git

我运行了一个应该创建git标签的脚本。

当我搜索该标记时:books { margin: 1em; border-spacing: 2px; border-collapse: collapse; display: table; border: 1px solid black; } book { display: table-row; } title, price { display: table-cell; border: 1px solid black; padding: 2pt; }

我收到了提交:git show-ref --tags

然后,当我搜索包含该提交的分支时:

020795b07753c02034500f10f17dbc82edf refs/tags/my-tag

我得到一个分支:git branch --contains 020795b07753c02034500f10f17dbc82edf

问题在于,如果我通过feature/my-feature(使用020795b07753c02034500f10f17dbc82edf获得)的日志搜索feature/my-feature,我找不到它。

知道为什么标签指向不在日志中的提交吗?

1 个答案:

答案 0 :(得分:1)

正如Lasse V. Karlsen在评论中所说,你所拥有的是带注释的标签

没有意义的部分是您的评论 - 如果您运行git cat-file -p 020795b07753c02034500f10f17dbc82edf会发生什么。你说你得到了:

object 020795b07753c02034500f10f17dbc82edf
type commit
tag my-tag [maven-release-plugin]
copy for tag my-tag

这意味着您发现了另一个哈希冲突:ID为020795b07753c02034500f10f17dbc82edf的标记对象,以及指向ID为020795b07753c02034500f10f17dbc82edf的提交对象的标记对象。这实际上是不可能的 - 不是碰撞是不可能的(参见https://shattered.it/),而是Git在一个ID下存储了两个不同的对象。这是因为Git是对象的“真实名称”,它找到对象内容的方式,哈希ID。一旦Git存储了一个具有一个ID的对象,它就会拒绝存储具有相同ID的另一个不同对象。如果020795b07753c02034500f10f17dbc82edf已经是提交,则会拒绝尝试删除名称020795b07753c02034500f10f17dbc82edf下的标记。

以下是Git本身Git存储库中带注释标记的示例:

$ git show-ref --tags
[massive amount of output snipped]
f883596e997fe5bcbc5e89bee01b869721326109 refs/tags/v2.9.3

此处v2.9.3是标记名称 - refs/tags/ namespace中的引用 - 指向Git对象f883596e997fe5bcbc5e89bee01b869721326109。对象本身是带注释的标记:

$ git cat-file -t f883596e997fe5bcbc5e89bee01b869721326109
tag

及其内容是标记对象,它指向提交对象:

$ git cat-file -p f883596e997fe5bcbc5e89bee01b869721326109
object e0c1ceafc5bece92d35773a75fff59497e1d9bd5
type commit
tag v2.9.3
tagger Junio C Hamano <gitster@pobox.com> 1471018679 -0700

Git 2.9.3
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1

iQIcBAABAgAGBQJXrfa3AAoJELC16IaWr+bLLY8QANE8ZaL+qyhjC8fHfJhhr4cY
GeZe8x9SSTNv0WzOvXGf34XwdpOYYiVrUrwlgBx6HglhDeYzCp4kObR5sHwtTKgN
r0KKvAuvjlZJm5tWNavu2fDoHKhE+QRP3AagaF5iDX68QLjhGOS8+zAWqNRukh7y
X6tmdUhGhWPtUKr1LBUVd94GdF8v5tggCNDcqZZj+dPIosPvlDqGWT29/IKyCU/a
4o91hD5jWkMybfyTwzZDsSYmtB4TXxML8idJUdZQ5LyyPq9uSU63lgP8ljwivYzy
oiVB1OOawym7+PeyvZEvLvpFW1Ks7YSTCMNQjn4Y3dxYF3szuoPZV3ztCzngoEIG
qSuzA0sn6zfaMWAQF2Yjix2zBfSlBXmxNzA/WqYAyNr3Lsias5A/X9nFtowSEi56
0iFVilSsKWc3bC0oNEyYFlUs1kY4rR2S5kbBXTJ6l75bvDvXP/L+JXm4QcRCr92i
6i7NYxeNqfnZZV72KeG2EqZaL4mrXAY68Mjv8jd/80oogCUDBhlTKd8IK/WG64M9
VjfHpvKmtkBaIq6Zz0cQxO1pe4F64GzSNzlC9l787iQCnUW+4BO7OyEAByJWzHn+
D5oSfWI79MDVdvw2UlHvk1tg4bNNYLcNwTGZGQhcwXudv7hpzW3s1PBNY0LzXGux
LBOdlVeCcsYGr2rsRMbm
=PhTI
-----END PGP SIGNATURE-----

(此特定标签具有GPG签名)。实际的提交e0c1ceafc5bece92d35773a75fff59497e1d9bd5。这是(不同的)提交对象,包含在各种分支中。标记对象位于 no 分支中。除了哈希ID之外,您或Git找到标记对象的方式是查找标记名refs/tags/v2.9.3。然后通过读取标记对象找到 commit

由于此标记对象引用了其他Git对象e0c1ceafc5bece92d35773a75fff59497e1d9bd5,因此该注释标记的目标(我的术语)。标记对象声称目标的类型为commit,因此git cat-file -t应该说它是提交,它确实:

$ git cat-file -t e0c1ceafc5bece92d35773a75fff59497e1d9bd5
commit

并且提交对象依次正常:

$ git cat-file -p e0c1ceafc5bece92d35773a75fff59497e1d9bd5
tree 3cc4bf42e1b9aaa3c650af7247019890f7e01c95
parent 9b601eafd1437df2e11b032bfbfd1ac5d32d3290
author Junio C Hamano <gitster@pobox.com> 1471018671 -0700
committer Junio C Hamano <gitster@pobox.com> 1471018671 -0700

Git 2.9.3

Signed-off-by: Junio C Hamano <gitster@pobox.com>

并且在Git-land中一切都很好。