剥离在Git中意味着什么?

Ed *_*d I 9 git

在尝试理解与git提交相关联的JGit:Retrieve标签时,我到达了JGit邮件列表上的这个线程: [jgit-dev]提交和标记.

在这个线程中,他们引用的peel方法org.eclipse.jgit.lib.Repository:

剥离对带注释标签的可能没有剥离的引用.

我只能在Git文档中找到两个剥离提示:git-check-ref-format(1)Manual PageGit Internals - 维护和数据恢复.

剥离术语在Git中意味着什么?它有用吗?它与洋葱有什么关系?

tor*_*rek 10

您已经知道存储库中的每个对象都具有唯一的SHA-1,以及相关的类型和内容.(从命令行,用于查看给定对象的类型,并查看内容,可能应用了一些漂亮的打印,但通常格式相当粗糙.)git cat-file -t sha1git cat-file -p sha1

git存储库中带注释的标记对象包含SHA-1.(我希望这部分是明确的,没有争议的.:-))

通常,带注释的标记对象内的SHA-1称为"目标ID",因此命名为标记的"目标"的对象是提交对象的ID.在这种情况下,一切仍然非常清晰和简单.但如果不是呢?

特别是,带注释的标签的目标可能是另一个带注释的标签.如果是这种情况,则必须获取第二个带注释的标记,该标记包含另一个目标ID.您必须重复此过程,在标记之后剥离标记,直到到达非标记对象.理想情况下,这将是一个提交,但当然它可以是剩下的三种对象中的任何一种(虽然不清楚标记树或blob意味着什么;只有提交才有意义).

这种"剥皮"过程已被比作剥洋葱,这就是短语的起源.

请注意,如果你在写一个仓库健康检查,这可能是明智的,以确保标签的链不循环(例如,如果标签1234567具有7654321作为其目标,并且7654321是一个注释标签以1234567作为其目标?).(编辑:正如remram在评论中指出的那样,这需要"打破"SHA-1.这意味着它几乎不可能在实践中发生,就像你不会得到递归指向自己的树一样.)

编辑:如何制作指向另一个标记的标记:

... make a repo with a commit that can be tagged ...
$ git tag -a anno1 -m 'annotated tag'
$ git tag -a anno2 anno1 -m 'another tag'
$ git cat-file -p anno1
object d4ec8b2d465de0c087d645f52ba5040586b8ce0f
type commit
tag anno1
tagger Chris Torek <chris.torek@gmail.com> 1413933523 -0600

annotated tag
$ git cat-file -p anno2
object cd1e0637c348e46c645819ef6de36679052b4b7f
type tag
tag anno2
tagger Chris Torek <chris.torek@gmail.com> 1413934239 -0600

another tag
Run Code Online (Sandbox Code Playgroud)

  • 这是错误的。带注释的标签对象只能指向提交对象,不能指向其他标签。标签链不能循环的原因与提交链不能循环的原因相同——SHA1 函数是不可逆的。 (2认同)
  • @remram:关于 SHA-1 不可逆的观点是有效的,除了有人声称已经破坏了它(我不确定是否相信他们)或至少有能力破坏它。至于不指向标签的标签,确实`git tag -a`默认不会这样做,但我能够制作一个指向另一个标签的标签;我会编辑帖子。它工作得很好:`git show anno3` 显示了指向标签 `anno1` 的标签,然后是 `anno1` 上的底层提交(`anno2` 是一个演示,`git tag -a` 用于底层提交)。 (2认同)

rem*_*ram 5

“剥离”是指取消引用,例如从引用到带注释的标记对象再到它指向的提交上的引用。

该术语也用于^{xxx}语法的其他情况,例如从提交到树abc1234^{tree}