据我所知,如果你在git中添加一个子模块,那么主repo包含一个指向子模块的某个提交的指针。有没有办法在不检查子模块代码的情况下,查看主代码库指向特定子模块的哪个提交?
7uhlpewt1#
正如其他答案所解释的,您可以使用两个命令:
git submodule status
git ls-tree HEAD
commit
git ls-tree HEAD | awk '$2 == "commit"'
有什么区别?
git log
git rev-parse HEAD
git submodule update
它们不同的典型情况是,当您git checkout另一个分支/标记/提交时,或者您使用git pull更新当前分支时。这两个命令都将导致HEAD更新到相应的提交。现在,如果这个提交指定你的子模块必须使用不同的版本,git submodule status仍然会显示旧版本,但是git ls-tree HEAD显示的目标已经是新版本了。
git checkout
git pull
HEAD
有没有更简单的方法来注意它们不同步?
检查git submodule status的输出。正如手册所解释的,如果在哈希之前有一个+,这意味着当前 checkout 的版本和目标版本是不同的。
+
如何使它们恢复同步?
运行git submodule update:新的子模块将被加载,并且两个命令将指示相同的提交。
例如,假设在我们的repo中有一个名为base的子模块。git submodule status的输出是(注意+):+059ca6c4940813aa956e8668cb0af27efa189b22基础版(1.2版)git ls-tree HEAD的输出是提交fbc 447 ef 9468 def 36 cf 4089094 d 6960 cc 51618 b3基正如我们所看到的,哈希是不同的。事实上,+已经通知了我们。现在,如果我们输入git submodule update,它会说:子模块路径'base':已 checkout 'fbc 447 ef 9468 def 36 cf 4089094 d 6960 cc 51618 b3'现在我们可以使用的所有命令(base内部的git submodule status、git ls-tree HEAD和git log)都表示fbc447ef9468def36cf4089094d6960cc51618b3,在git submodule status的输出中,它前面没有+。如果我们再次运行git submodule update,什么也不会发生,因为一切都已经是最新的,甚至没有任何输出。1:检查子模块的提交时必须小心,因为这很棘手:要查找子模块base中的最后一次提交,您不能使用git log base,您必须进入该目录(cd base),然后从那里运行git log。原因是第一个命令列出了“主”仓库的提交,这些提交设置了子模块的新版本,并且这些提交完全独立于子模块内部的提交。
base
fbc447ef9468def36cf4089094d6960cc51618b3
git log base
cd base
t40tm48m2#
一个更直接的命令是:git submodule status
7tofc5zh3#
当然;有几种方法:
git ls-tree <commit> <relative path to submodule>
git ls-tree <commit>:<absolute path to parent of submodule>
git ls-tree <commit>:./<relative path to parent of submodule>
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/docs
git ls-tree -r HEAD
子模块将显示为类型commit(而不是通常的blob或tree)。
blob
tree
lx0bsm1f4#
原谅我的潜伏,但我相信最初问题的答案可能是:
git submodule status --cached
“git submodule status”告诉你哪个提交被 checkout ,“--cached”告诉你哪个提交“git submodule update”会被 checkout 。我不知道--cached是什么时候被添加到git的。
kkbh8khc5#
git ls-tree -r <submodule-commitID-of-interest> <submodule-path> | awk '{print $3}'
这里有一个bash行来打印子模块的repo commit ID,最后10个子模块的commit ID指向:
bash
git --no-pager log -10 --pretty="%H" <submodule-path> | while read i; do git ls-tree -r $I <submodule-path> | awk '{print $3}'; done
u0njafvf6#
accepted answer返回一个4列输出,其中包含子模块gitlink指向的提交。这对于验证所指向的路径确实是一个子模块很有用,例如当用户在脚本中提供输入时。为此,请验证第二列是否等于“commit“,例如:使用awk。但是,如果不需要此检查,则可以使用以下方法之一生成一个更简单的输出,该输出仅包含子模块提交,而没有其他内容:
awk
git rev-parse HEAD:./<relative-path> git rev-parse HEAD:<repository-path>
其中<relative-path>是子模块相对于shell工作目录的路径,<repository-path>是子模块相对于存储库根目录的路径。可以使用任何分支名称、提交散列或其他有效的修订描述(参见man git rev-parse)来代替HEAD。
<relative-path>
<repository-path>
man git rev-parse
6条答案
按热度按时间7uhlpewt1#
正如其他答案所解释的,您可以使用两个命令:
git submodule status
,或git ls-tree HEAD
,只取第二列为commit
的行(如果你有awk,你可以使用git ls-tree HEAD | awk '$2 == "commit"'
)。但是,这些命令给出的结果给予不同!
有什么区别?
git submodule status
总是报告 * 当前 * 状态(顾名思义),即当前已 checkout 的提交。您在这里看到的散列与您进入子模块的目录1并检查最新提交(使用git log
或git 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
的输出。正如手册所解释的,如果在哈希之前有一个+
,这意味着当前 checkout 的版本和目标版本是不同的。如何使它们恢复同步?
运行
git submodule update
:新的子模块将被加载,并且两个命令将指示相同的提交。示例
例如,假设在我们的repo中有一个名为
base
的子模块。git submodule status
的输出是(注意+
):+059ca6c4940813aa956e8668cb0af27efa189b22基础版(1.2版)
git ls-tree HEAD
的输出是提交fbc 447 ef 9468 def 36 cf 4089094 d 6960 cc 51618 b3基
正如我们所看到的,哈希是不同的。事实上,
+
已经通知了我们。现在,如果我们输入
git submodule update
,它会说:子模块路径'base':已 checkout 'fbc 447 ef 9468 def 36 cf 4089094 d 6960 cc 51618 b3'
现在我们可以使用的所有命令(
base
内部的git submodule status
、git ls-tree HEAD
和git log
)都表示fbc447ef9468def36cf4089094d6960cc51618b3
,在git submodule status
的输出中,它前面没有+
。如果我们再次运行git submodule update
,什么也不会发生,因为一切都已经是最新的,甚至没有任何输出。1:检查子模块的提交时必须小心,因为这很棘手:要查找子模块
base
中的最后一次提交,您不能使用git log base
,您必须进入该目录(cd base
),然后从那里运行git log
。原因是第一个命令列出了“主”仓库的提交,这些提交设置了子模块的新版本,并且这些提交完全独立于子模块内部的提交。t40tm48m2#
一个更直接的命令是:
git submodule status
7tofc5zh3#
当然;有几种方法:
git ls-tree <commit> <relative path to submodule>
git ls-tree <commit>:<absolute path to parent of submodule>
git ls-tree <commit>:./<relative path to parent of submodule>
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
,它实际上是repo中的一个常规目录。git ls-tree -r HEAD
列出了你的代码库中的所有内容,包括子模块。子模块将显示为类型
commit
(而不是通常的blob
或tree
)。lx0bsm1f4#
原谅我的潜伏,但我相信最初问题的答案可能是:
“git submodule status”告诉你哪个提交被 checkout ,“--cached”告诉你哪个提交“git submodule update”会被 checkout 。
我不知道--cached是什么时候被添加到git的。
kkbh8khc5#
这里有一个
bash
行来打印子模块的repo commit ID,最后10个子模块的commit ID指向:u0njafvf6#
accepted answer返回一个4列输出,其中包含子模块gitlink指向的提交。这对于验证所指向的路径确实是一个子模块很有用,例如当用户在脚本中提供输入时。为此,请验证第二列是否等于“
commit
“,例如:使用awk
。但是,如果不需要此检查,则可以使用以下方法之一生成一个更简单的输出,该输出仅包含子模块提交,而没有其他内容:
其中
<relative-path>
是子模块相对于shell工作目录的路径,<repository-path>
是子模块相对于存储库根目录的路径。可以使用任何分支名称、提交散列或其他有效的修订描述(参见man git rev-parse
)来代替HEAD
。