查看 git 提交,包括当时的子模块
Check out a git commit including submodules as they were at that time
我们如何检查包含子模块的 git 提交,它们当时?
我们可能想要这样做的一个原因是查看主程序的先前版本,我们需要使用提交时使用的版本中的子模块重建主程序。
鉴于此,我们甚至可以在常规工作流程中使用它:
- 首先用
git submodule update --remote --merge
更新所有子模块,然后尝试构建以查看程序是否可以使用所有子模块的最新版本。
- 如果成功,我们就完成了。如果它不起作用,那么我们可以转到以前版本的程序,包括。它使用的子模块版本及其工作。
- 然后逐个更新子模块并更改程序以使用它们。
我们可以通过手动查看每个子模块来做到这一点:哪个提交具有适当的时间戳(并希望该程序使用当时最新的版本)。如果我们能看到程序的提交 X 使用了子模块提交 Y,那就更好了。并检查每个子模块。
在这种情况下,您只需要 运行 git submodule update --checkout
(没有 --merge
,没有 --remote
)检查之前的提交。
关于子模块有很多混淆。虽然基础实际上相当简单:
- 每个子模块都是自己的 Git 存储库。
- 从子模块中,将 "containing" Git 称为 超级项目。
- 超级项目记录 URL 和路径——这些是您通常由 运行ning
git clone
控制或提供的东西——对于 .gitmodules
中的每个子模块] 文件。
- 同时,当您在超级项目中进行提交时,此提交在其快照中像往常一样包含所有正常的树和文件,而且对于每个子模块,在检出子模块。1
这具有 "freezing" 将适当的子模块提交到每个超级项目提交中的效果。它是——或者最初是——用于管理第三方代码,与超级项目相比,子模块本身很少改变。
这种模式一点都不灵活,不适合很多人想要使用子模块的方式,也就是把子模块放在某个分支的顶端。因此,子模块增加了更新分支名称的能力,或者成为 worked-in 并使工作变基 and/or 合并。这些新能力产生了 子模块。<em>name</em>.update
配置条目和 git submodule update --remote
选项。
如果您没有配置任何这些项目,git submodule update
将单独检查当前记录的每个子模块所需的(记录的)子模块提交,即, HEAD
, 超级项目的提交。如果您已经配置了其中的一些,您可以使用git submodule update --checkout
覆盖配置并导致git检出<em>hash-id</em>
在每个子模块中。请注意,添加 --force
会使 Git 执行此子模块检出,即使 HEAD
已经在该条目中。但是由于每个子模块都是它自己的 Git 存储库,因此子模块的签出与它自己的 (per-repository / per-work-tree) 索引和 work-tree. 有自己的交互2
同样,每个子模块都是自己的 Git 存储库,这意味着当前超级项目的子模块可能有自己的子模块。如果是这样,这也使子模块成为超级项目,这就是 --recursive
标志的用武之地。如果您不嵌套子模块,none 这种复杂性将影响您。
1换句话说,超级项目的index每个子模块都有一个条目。这个索引条目的类型是"gitlink",它存储了子模块中从HEAD
读取的SHA-1。这些 gitlink 条目被视为 symlink 和目录之间的一种奇怪的交叉。
2也就是说,如果你手动输入了其中一个子模块并修改了索引and/or work-tree,那么git checkout
运行 inside 该子模块(如果有)可能仍会将您的修改带入新的 checked-out 提交。
我们如何检查包含子模块的 git 提交,它们当时?
我们可能想要这样做的一个原因是查看主程序的先前版本,我们需要使用提交时使用的版本中的子模块重建主程序。
鉴于此,我们甚至可以在常规工作流程中使用它:
- 首先用
git submodule update --remote --merge
更新所有子模块,然后尝试构建以查看程序是否可以使用所有子模块的最新版本。 - 如果成功,我们就完成了。如果它不起作用,那么我们可以转到以前版本的程序,包括。它使用的子模块版本及其工作。
- 然后逐个更新子模块并更改程序以使用它们。
我们可以通过手动查看每个子模块来做到这一点:哪个提交具有适当的时间戳(并希望该程序使用当时最新的版本)。如果我们能看到程序的提交 X 使用了子模块提交 Y,那就更好了。并检查每个子模块。
在这种情况下,您只需要 运行 git submodule update --checkout
(没有 --merge
,没有 --remote
)检查之前的提交。
关于子模块有很多混淆。虽然基础实际上相当简单:
- 每个子模块都是自己的 Git 存储库。
- 从子模块中,将 "containing" Git 称为 超级项目。
- 超级项目记录 URL 和路径——这些是您通常由 运行ning
git clone
控制或提供的东西——对于.gitmodules
中的每个子模块] 文件。 - 同时,当您在超级项目中进行提交时,此提交在其快照中像往常一样包含所有正常的树和文件,而且对于每个子模块,在检出子模块。1
这具有 "freezing" 将适当的子模块提交到每个超级项目提交中的效果。它是——或者最初是——用于管理第三方代码,与超级项目相比,子模块本身很少改变。
这种模式一点都不灵活,不适合很多人想要使用子模块的方式,也就是把子模块放在某个分支的顶端。因此,子模块增加了更新分支名称的能力,或者成为 worked-in 并使工作变基 and/or 合并。这些新能力产生了 子模块。<em>name</em>.update
配置条目和 git submodule update --remote
选项。
如果您没有配置任何这些项目,git submodule update
将单独检查当前记录的每个子模块所需的(记录的)子模块提交,即, HEAD
, 超级项目的提交。如果您已经配置了其中的一些,您可以使用git submodule update --checkout
覆盖配置并导致git检出<em>hash-id</em>
在每个子模块中。请注意,添加 --force
会使 Git 执行此子模块检出,即使 HEAD
已经在该条目中。但是由于每个子模块都是它自己的 Git 存储库,因此子模块的签出与它自己的 (per-repository / per-work-tree) 索引和 work-tree. 有自己的交互2
同样,每个子模块都是自己的 Git 存储库,这意味着当前超级项目的子模块可能有自己的子模块。如果是这样,这也使子模块成为超级项目,这就是 --recursive
标志的用武之地。如果您不嵌套子模块,none 这种复杂性将影响您。
1换句话说,超级项目的index每个子模块都有一个条目。这个索引条目的类型是"gitlink",它存储了子模块中从HEAD
读取的SHA-1。这些 gitlink 条目被视为 symlink 和目录之间的一种奇怪的交叉。
2也就是说,如果你手动输入了其中一个子模块并修改了索引and/or work-tree,那么git checkout
运行 inside 该子模块(如果有)可能仍会将您的修改带入新的 checked-out 提交。