为什么 Git 只存储 refs/remotes/origin 下的分支?

Why does Git only store branches under refs/remotes/origin?

在查看了 Git 标签并查看了它们的传播方式以及有多少变通方法可以 修剪 它们后,我得出结论,最好的解决方法是更改refs/remotes/origin/ 的结构。那么,为什么 refs/remotes/origin/ 下的 refs 被假定为分支?复制远程引用下的顶级结构也很容易:

refs/remotes/origin/heads/  <-- remote tracking branches
refs/remotes/origin/tags/   <-- remote tracking tags
refs/remotes/origin/notes/  <-- remote tracking notes

但是所有与 Git 一起使用的工具都假定 refs/remotes/origin/ 下的引用是分支。

事情之所以如此,是否有实际原因,还是仅仅是一个意外?

编辑 1:

进一步研究后,我发现 git log --decorate 会在 refs/remotes/origin/tags/* 下正确显示 带注释的标签 轻量级标签 显示为分支。

配置文件:

[remote "origin"]
    url = ssh://git@github.com/test/example.git
    fetch = +refs/heads/*:refs/remotes/origin/heads/*
    fetch = +refs/tags/*:refs/remotes/origin/tags/*

轻量级标签:

commit e447ca1e2f3c765072c6bd783981619da3d6a090 (tag: v0.2, origin/tags/v0.2)
Author: Joanna Blogs <joanna@blogs.com>
Date:   Thu Aug 18 14:38:48 2016 -0500

    Testing out a light weight tag

带注释的标签:

commit 334d587e8f9bad1756665384056760c0cb798f32 (tag: v0.1, tag: origin/tags/v0.1)
Author: Joe Blogs <joe@blogs.com>
Date:   Fri Jul 1 09:24:25 2016 -0500

    Testing an annotated tag

然而,正如预期的那样,git tag -l 命令根本不显示它们。

[在回答后不到一天就进行了编辑:之前的回答是基于一个不同的、记错的问题。]

标签是全球性的/通用的。也就是说,在 Git 中没有 "remote tag".

这样的东西

没有技术原因 Git 不能有远程标签。事实上,它可以同时具有远程跟踪标签(始终强制更新) 全局标签(不强制更新)。这是手动实现它们的一种方法:

[remote "R"]
    url = ...
    fetch = +refs/heads/*:refs/remotes/R/*
    fetch = +refs/tags/*:refs/rtags/R/*
    fetch = refs/tags/*:refs/tags/*

现在当你 git fetch R 时,如果你已经有一个标签 blue 而他们有一个不相关的 blue,你会得到 refs/rtags/R/blue 但不会更新你的拥有 refs/tags/blue.

(这不是很方便,因为您必须拼出 rtags/R/blue,但如果发生碰撞,您无论如何都必须拼出以避免歧义。)

如果您要问:"remote tags instead of global tags seem like a good idea, why doesn't Git do them?",我的回答是 "history, inertia, stubbornness, etc.",但您当然必须直接询问 Git 维护者。 (删除全局标签似乎很不礼貌。:-))

如果你问 "remote tags in addition to global tags seems like a good idea, why doesn't Git do them?",我的回答是 "I don't know"。的确,我必须将它放在 refs/rtags/R 而不是 refs/remotes/R/tags/ 下,因为 refs/remotes/R 中除了分支之外没有其他空间。如果 Git 的人完全普遍地采用这个,也许你自己暗示的建议,简单地将 refs/* 复制到 refs/remotes-new/*,然后自动将它们视为标签、注释等,最好。