如何解决git 子模块跟踪标签
我知道如何添加跟踪分支 (-b branchname
) 的子模块,但我想知道是否有类似的功能来跟踪标签。
假设我在子模块存储库中有一个特定项目的标签。我在子模块 repo 中添加新功能并将标签拉到某个提交。我希望使用子模块的项目来跟踪标签,而不必在项目存储库中进行额外的提交。
这可能吗?
问候
解决方法
实际上,即使使用 -b
选项,Git 子模块也始终通过原始哈希 ID 指定特定的提交。 -b
选项值得注意的是 Git 并没有真正使用它,换句话说。1 ?但这不是你想要的:你想要一个特定的标签.
现在,关于 Git 标签的事情是这样的:它永远不应该移动。这意味着,一旦将其简化为基本概念,标签名称只是某些特定原始哈希 ID 的人类可读名称,它应该总是意味着那个 哈希 ID。这将标记名称与分支名称区分开来:分支名称是特定散列 ID 的名称,但名称 br1
的散列 ID,br1
是分支名称,应该更改时间。
另一种表述方式是:
-
分支名称总是表示最新提交,而不是一个特定的提交,不管最近发生了什么.
-
标签名称总是意味着我们在特定日期挑选的一个特定提交。本质上,这是分支名称的相反。
但是,鉴于上述情况以及子模块的工作方式——超级项目通过原始哈希 ID 指定子模块提交——使用标签名称没有要点。如果标签名称 tag1
意味着永远提交 a123456
,那么使用名称 tag1
而不是原始哈希 ID 的唯一原因是供人类消费......并且子模块引用不是人类消费,Git。所以你只想选择一个提交并坚持下去,这就是子模块已经做到的。
换句话说,不要打扰。唯一会产生影响的情况是您移动了标签,而您不应该移动标签。如果你正在移动标签——不时选择一个不同的提交——你正在滥用它们:应该移动的是分支名称,不是标签名称。别这样了。2
1显然,Git 确实在某处记录了分支名称。然后你可以让 Git 使用它。但是,该方法并不明显,而且 git submodule update
对它有点奇怪。这里真正的关键是超级项目 Git 存储库始终将子模块存储库保持在 分离的 HEAD 上。即使指定了分支名称,子模块仍然使用 detached-HEAD 模式。所以它实际上并没有使用分支名称——无论如何也不是直接使用。这个想法不一定非常好实现,是超级项目 Git 可以命令子模块 Git 从某个第三 Git 存储库git fetch
,然后使用 git rev-parse
翻译一些远程-将与分支名称相关的名称跟踪到一个哈希 ID 中,从而以某种方式到达正确的哈希 ID 以用于子模块中的分离 HEAD 检出。
这一切都相当麻烦和复杂。子模块支持正在作为一个正在进行的项目得到改进,它可能有一天会变得更简单和更明智,但就目前而言,我个人的建议是,如果您希望“子模块”具有类似分支的行为,请不要直接使用 git submodule
本身这里。只需进入子模块,将其视为常规 Git 存储库,像往常一样运行 git checkout
或 git switch
,然后在那里进行工作以使其更新并检查正确的提交。然后,退出子模块回到超级项目,并使用git add
更新超级项目存储库的索引以记录新的正确哈希ID。
如果您按照我的方式进行所有操作,则根本不需要 -b
选项。如果您愿意,您可以将其用作自我提醒。
如果您有足够现代的 Git,git submodule update --remote
可以稍微简化一下。我知道这在 Git 1.5/1.6 中效果不佳;它可能早在 1.7 或 1.8 就可以了,这将使它在今天运行得相当好,因为即使是较旧的 Linux 发行版现在也带有 1.7 或 1.8 版本。从大约 2.5 开始,大约是 git worktree
出现的时间,它可能没问题。
2当然,有了 Git,你就在掌控之中。如果你有一个非常好的理由来移动标签,并且知道它会如何破坏使用你的存储库的其他人的头脑,那么你实际上可以移动标签。但是随后您需要通过进行新提交来移动子模块提交。另见脚注 1。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。