如何查看git子模块指向哪个提交

git*_*rik 10 git git-submodules git-commit

据我所知,如果你在git中添加一个子模块,那么它指向该子模块中的某个提交.

是否有任何方法可以查看子模块指向哪个提交而不检查它?

Jan*_*ger 19

当然; 有几种方法:

  1. git ls-tree <commit> <relative path to submodule>
  2. git ls-tree <commit>:<absolute path to parent of submodule>
  3. git ls-tree <commit>:./<relative path to parent of submodule>
  4. git ls-tree -r <commit> <relative path to parent of submodule>

到目前为止,第一个对于检查单个子模块是最简单的。

如果您想检查包含在同一目录中的多个子模块,但您不想递归到任何其他不是子模块的子目录,则第二个/第三个是最简单的。(:默认情况下,语法使用存储库的顶级作为其参考点,而不是您当前的工作目录,因此./如果您现在正处于存储库的深处,请务必包含前缀。)

如果在一个目录中有很多子模块,并且只有子模块,则第四个最简单。

例子:

  • git ls-tree HEAD src/thirdparty/libfoo 显示子模块,没有别的。
  • git ls-tree HEAD:src/thirdparty直接为您提供下面的所有内容src/thirdparty,包括您的子模块src/thirdparty/libfoo
  • git ls-tree -r HEAD src/thirdparty直接为您提供下面的所有内容src/thirdparty,包括您的子模块src/thirdparty/libfoo,但也会递归到src/thirdparty/docs它实际上是您的回购中的常规目录。
  • git ls-tree -r HEAD 绝对列出您的 repo 中的所有内容,包括子模块。

子模块将显示为类型commit(而不是通常的blobtree)。

  • 这似乎不起作用(不再?)。我做了 `git ls-tree HEAD:some/path` (其中 some/path 是一个子模块)并且 git 输出 `fatal: not a tree object`。我正在使用 git 2.25.0。 (3认同)
  • @mic 那么你需要使用`some`。我想我的示例有点难以阅读,但其想法是列出子模块的父模块,而不是子模块本身。 (2认同)
  • `git ls-tree master &lt;path&gt;` 为我工作 git 2.25.0 (2认同)

use*_*647 17

请原谅潜伏,但我相信最初问题的答案可能是:

git submodule status --cached
Run Code Online (Sandbox Code Playgroud)

“git submodule status”告诉您哪个提交已签出“--cached”告诉您“git submodule update”将签出哪个提交。

我不确定 --cached 何时被添加到 git 中。


Fab*_*ica 13

正如其他答案所解释的,您可以使用两个命令:

  • git submodule status, 要么
  • git ls-tree HEAD,仅采用第二列所在的行commit(如果有awk,则可以使用git ls-tree HEAD | awk '$2 == "commit"')。

但是,这些命令会产生不同的结果!

有什么不同?

  • git submodule status 总是报告当前状态(顾名思义),即当前已检出的提交。您在此处看到的哈希与通过进入子模块的目录1并检查最新的提交(使用git loggit rev-parse HEAD)所看到的相同。
  • git ls-tree HEAD 显示目标状态,不一定是当前状态。如果要更新子模块,使其与指定版本相对应,则必须使用git submodule update

是什么导致当前状态和目标状态不同?

它们不同的典型情况是当您git checkout另一个分支/标记/提交时,或者您git pull用来更新当前分支时。这两个命令都将导致HEAD更新为相应的提交。现在,如果此提交指定您的子模块必须使用其他版本,git submodule status则仍将显示旧版本,但显示的目标git ls-tree HEAD将已经是新版本。

有没有更简单的方法来通知它们不同步?

检查的输出git submodule status如手册所述,如果+在哈希值之前有一个,则表示当前签出的版本与目标版本不同。

如何将它们同步恢复?

通过运行git submodule update:将加载新的子模块,并且两个命令都将指示相同的提交。

例如,假设在我们的仓库中有一个名为的子模块base
的输出git submodule status是(请注意+):

+ 059ca6c4940813aa956e8668cb0af27efa189b22基本版本(1.2版)

和的输出git ls-tree HEAD

160000提交fbc447ef9468def36cf4089094d6960cc51618b3基本

我们可以看到,哈希值是不同的。实际上,+已经通知了我们。

现在,如果我们输入git submodule update,它将显示:

子模块路径'base':检出'fbc447ef9468def36cf4089094d6960cc51618b3'

现在,我们可以使用的所有命令(git submodule statusgit ls-tree HEADgit log从内部base)指示了fbc447ef9468def36cf4089094d6960cc51618b3,并且+输出中没有前面的命令git submodule status。如果我们git submodule update再次运行,则什么也不会发生,因为一切都已经是最新的,甚至没有任何输出。


1:检查子模块的提交时必须小心,因为它很棘手:要找到base您不能使用的子模块中的最后一次提交,git log base必须输入该目录(cd base),然后git log从那里运行。原因是第一个命令列出了设置了子模块新版本的“主”存储库的提交,并且这些提交完全独立于在子模块内部进行的提交。


小智 6

更直接的命令是:

git submodule status