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

时间:2016-09-08 21:01:05

标签: git git-refspec

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

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命令根本不会显示它们。

1 个答案:

答案 0 :(得分:3)

[回答后大约不到一天编辑:之前的回答基于一个不同的,错误记忆的问题。]

标签旨在全球/通用。也就是说,在Git中没有这样的东西作为“远程标签”。

没有技术原因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 {1}}。

(这不是那么方便,因为你必须拼出rtags/R/blue,但是在碰撞的情况下,你必须拼出来以避免歧义。)

如果你问:“远程标签而不是全局标签似乎是一个好主意,为什么Git不这样做?”,我的回答是“历史,惯性,固执, “,但当然你真的要直接问Git维护者。 (删除全局标签似乎不礼貌。:-))

如果你问“远程标签除了全局标签似乎是一个好主意,为什么Git不这样做呢?”我的回答是“我不知道”。确实,我必须将其置于refs/rtags/R而不是refs/remotes/R/tags/之下,因为refs/remotes/R中除了分支以外的任何内容都没有空间。如果Git人员完全采用这一点,也许你自己隐含的建议,简单地将refs/*复制到refs/remotes-new/*,然后自动将它们视为标签,注释等,将是最好的。