'git子模块更新'总是获取相同的提交

r6hnlfcb  于 2022-12-21  发布在  Git
关注(0)|答案(1)|浏览(122)

我有一个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 的是哪个提交,但这是可以预料到的,因为2fd6ace341b24f的祖先。

ajsxfq5m

ajsxfq5m1#

git submodule update通常表示:

  • 获取子模块列表
  • 对于每个子模块:
  • 查找提交哈希ID:它存储在超级项目的索引中,所以运行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。

  • x1米25英寸1x、x1米26英寸1x、x1米27英寸1x:这些控制一旦获得散列ID,就对它 * 做什么 。操作(switch --detachmergerebase 在子模块库中 * 并且 * 使用通过获得散列ID步骤 * 获得的散列ID发生。

我认为您在这里所要求的只是--no-fetch选项,然而,子模块是〈insert body part〉中的一个大问题;让它们“按需”工作通常是非常棘手的,部分原因是我们通常甚至不确定“按需”在第一个地方的含义。当我们使用子模块时,我们都会以某种方式发现为什么人们称它们为 sob-模块......

相关问题