我有一个Git repo,它包含一个子模块和两个修改子模块HEAD的提交。如果我 checkout 其中一个提交,并执行git submodule update
,这会成功,而不必连接到远程,因为我可以在本地使用给定的提交。但是,如果我 checkout 另一个提交,git submodule update
总是执行一个获取(如果远程数据库不可访问,则会失败),即使它不断地重新获取相同的提交。
会话示例:
$ git checkout -q 9089923 && git submodule update
Submodule path 'chirp8-engine': checked out '341b24f2c3168a6e226ae3c249179426eff6dd99'
$ git checkout -q 289a15d && git submodule update
From github.com:gergoerdi/chirp8-engine
* branch 2fd6ace109f6337df97056aacdb40e5fb51f0e97 -> FETCH_HEAD
Submodule path 'chirp8-engine': checked out '2fd6ace109f6337df97056aacdb40e5fb51f0e97'
$ git checkout -q 9089923 && git submodule update
Submodule path 'chirp8-engine': checked out '341b24f2c3168a6e226ae3c249179426eff6dd99'
$ git checkout -q 289a15d && git submodule update
From github.com:gergoerdi/chirp8-engine
* branch 2fd6ace109f6337df97056aacdb40e5fb51f0e97 -> FETCH_HEAD
Submodule path 'chirp8-engine': checked out '2fd6ace109f6337df97056aacdb40e5fb51f0e97'
$ git checkout -q 9089923 && git submodule update
Submodule path 'chirp8-engine': checked out '341b24f2c3168a6e226ae3c249179426eff6dd99'
$ git checkout -q 289a15d && git submodule update
From github.com:gergoerdi/chirp8-engine
* branch 2fd6ace109f6337df97056aacdb40e5fb51f0e97 -> FETCH_HEAD
Submodule path 'chirp8-engine': checked out '2fd6ace109f6337df97056aacdb40e5fb51f0e97'
这是什么原因,我如何改变它,使git submodule update
不保持重取相同的提交?
- 编辑后添加**
我开始跟踪git
,差异都归结为git submodule--helper
的功能:
x一个一个一个一个x一个一个二个x
特别是,轨迹在一开始就发散:
$ GIT_TRACE=1 git submodule--helper run-update-procedure --oid 341b24f2c3168a6e226ae3c249179426eff6dd99 -- chirp8-engine
11:08:30.962038 git.c:455 trace: built-in: git submodule--helper run-update-procedure --oid 341b24f2c3168a6e226ae3c249179426eff6dd99 -- chirp8-engine
11:08:30.962259 run-command.c:668 trace: run_command: cd chirp8-engine; unset GIT_PREFIX; GIT_DIR=.git git rev-list -n 1 341b24f2c3168a6e226ae3c249179426eff6dd99 --not --all
11:08:30.963983 run-command.c:668 trace: run_command: cd chirp8-engine; unset GIT_PREFIX; GIT_DIR=.git git rev-list -n 1 341b24f2c3168a6e226ae3c249179426eff6dd99 --not --all
对比
$ GIT_TRACE=1 git submodule--helper run-update-procedure --oid 2fd6ace109f6337df97056aacdb40e5fb51f0e97 -- chirp8-engine
11:08:35.917283 git.c:455 trace: built-in: git submodule--helper run-update-procedure --oid 2fd6ace109f6337df97056aacdb40e5fb51f0e97 -- chirp8-engine
11:08:35.917522 run-command.c:668 trace: run_command: cd chirp8-engine; unset GIT_PREFIX; GIT_DIR=.git git rev-list -n 1 2fd6ace109f6337df97056aacdb40e5fb51f0e97 --not --all
11:08:35.919289 run-command.c:668 trace: run_command: cd chirp8-engine; unset GIT_PREFIX; GIT_DIR=.git git fetch
实际上,cd chirp8-engine; unset GIT_PREFIX; GIT_DIR=.git git rev-list -n 1 $SUBMODULE_COMMIT --not --all
的输出会有所不同,这取决于在子模块中 checkout 的是哪个提交,但这是可以预料到的,因为2fd6ace
是341b24f
的祖先。
1条答案
按热度按时间ajsxfq5m1#
git submodule update
通常表示:git rev-parse :chirp8-engine
;cd
到子模块库工作树中;git fetch
以 * 获取 * 提交;以及git switch --detach <hash>
以 * checkout * 该提交。这就是你现在看到的这就是子模块应该如何工作的。2“知道使用哪个提交”的是超项目,而不是子模块。
记住这一点:
git submodule update
总是执行提取操作(如果远程数据库不可访问,则会失败),即使它不断地重新提取相同的提交。指挥部可能会更聪明,但事实并非如此。
有几种方法可以让它以不同的方式运作:
git submodule update --no-fetch
:这告诉它 * 永远不要运行git fetch
*。如果你还没有你需要的提交,这会使git switch --detach
步骤失败,但它确实避免了git fetch
。git submodule update --remote
:这改变了哈希ID步骤(上面第一步)的工作方式,Git不再使用git rev-parse :<path>
从超级项目的索引中读取哈希ID,而是:git fetch
(除非被--no-fetch
抑制,在这种情况下根本不存在获取);那么git rev-parse
* 来获取哈希ID,使用的名称是通过将远程名称和分支名称粘贴在一起而构造的。这种粘贴的结果通常是一个远程跟踪名称,如origin/somebranch
,其中somebranch
是记录在submodule.<path>.branch
中的名称。此序列背后的一般思想是获取一个可能从未见过的散列ID,因为
git fetch
可能会更新一些远程跟踪名称。然后运行git fetch origin
,在保存foo
子模块的Git存储库中为origin/develop
获取一个新的哈希ID。现在我们在该子模块中运行git rev-parse origin/develop
以获取哈希ID,因此我们现在将更新(或使用合并或重定基)结果哈希ID。switch --detach
、merge
或rebase
) 在子模块库中 * 并且 * 使用通过获得散列ID步骤 * 获得的散列ID发生。我认为您在这里所要求的只是
--no-fetch
选项,然而,子模块是〈insert body part〉中的一个大问题;让它们“按需”工作通常是非常棘手的,部分原因是我们通常甚至不确定“按需”在第一个地方的含义。当我们使用子模块时,我们都会以某种方式发现为什么人们称它们为 sob-模块......