标签是提交的名称。因此,超级项目中的 tags/v2.11.0 标记是超级项目中特定提交的名称(即表示编号或哈希 ID)。所以这个:
git fetch --all --tags
git reset --hard tags/v2.11.0
有点奇怪,1但并不完全疯狂。
不过,每个子模块都是一个独立的 Git 存储库。那个单独的 Git 存储库可能有也可能没有标签 v2.11.0;如果它确实有这样的标签,则该标签将表示存在于其他 Git 存储库中的一些 other 提交:
标签仅在主模块中...
我假设这意味着每个子模块都没有这样的标签。
...所以它是子模块的远程标签
不,不是。没有“远程标签”之类的东西。标签只是提交哈希 ID 的名称,在任何给定的存储库中,您要么有标签,要么没有标签。如果你没有标签,你就没有那个名字。其他存储库的标记是该存储库中某个哈希 ID 的名称。
Git 是关于提交的。每个提交都有一个唯一的哈希 ID。这就是你用 Git 做的很多事情:你可能使用一个分支名称,如 master 或 develop 或其他,或者一个标签名称,如 v2.11.0,但你真的告诉 Git 让我提交 b0ff0cab1e...。 (完整的哈希 ID 又长又丑,但你可以通过以下方式找到它:
git rev-parse tags/v2.11.0
例如。)
使用超级项目的常规方法是在超级项目提交中为每个子模块提供正确的哈希 ID。这是提交本身的一部分,作为 Git 称为 gitlink 的实体。签出超级项目提交会导致将该 gitlink 放入超级项目 Git 的索引中。 Git 的索引现在保存为路径名和哈希 ID 对,例如 path/to/submodule 和 feedc0ffee...,可能希望子模块提交到 git checkout(作为分离的 HEAD)。
如果您想让每个子模块在该提交时成为一个分离的 HEAD,您现在可以运行:
git submodule update checkout
或:
git submodule update --recursive checkout
让子模块本身递归地检查它自己的任何子模块。
1--all 选项到git fetch 表示从所有远程获取。这在您使用它的上下文中有点意义,因为每个遥控器都可能有一些标签集,这将使您的 Git 将其标签的 all 复制到一个大规模的标签联合。如果存在冲突——如果远程 A 说标签 v1.2.3 应该表示 deadbeef 而远程 B 说标签 v1.2.3 应该表示 feedf00d,那么一般来说,无论您先选择哪个“获胜”。
git reset --hard 可能是错误的做法。如果您已经在分离的HEAD 上,这就像对给定标签执行git checkout,其副作用是丢弃任何尚未提交的工作。如果您在一个分支名称上,这会更改该分支名称中存储的哈希 ID,这可能是错误的。
总体而言,运行git fetch --tags,不运行--all,从当前远程获取,或者选择一个特定的远程信任可能更明智;或者如果只有一个遥控器,git fetch --tags 将使用那个遥控器,然后--all 是不必要的。然后,完成之后,使用git checkout tags/v2.11.0 或git switch --detach tags/v2.11.0,如果有未提交的工作,它们会报错。