[英]How to see which commit a git submodule points at
As far as I understand, if you add a submodule in git then, the main repo contains a pointer to a certain commit of the submodule.据我了解,如果你在 git 中添加一个子模块,那么主仓库包含一个指向子模块某个提交的指针。
Is there any way to see to which commit the main repo points at for a specific submodule, without checking out the code of the submodule?有没有办法查看特定子模块的主仓库指向哪个提交,而不检查子模块的代码?
As the other answers explain, you can use two commands:正如其他答案所解释的,您可以使用两个命令:
git submodule status
, or git submodule status
,或git ls-tree HEAD
, taking only the lines where the second column is commit
(if you have awk you can use git ls-tree HEAD | awk '$2 == "commit"'
). git ls-tree HEAD
,只取第二列commit
的行(如果你有 awk,你可以使用git ls-tree HEAD | awk '$2 == "commit"'
)。 What's the difference?有什么不同?
git submodule status
always reports the current status (as the name suggests), that is, the commit that is currently checked-out. git submodule status
总是报告当前状态(顾名思义),即当前签出的提交。 The hash that you see here is the same that you'd see by going into the submodule's directory 1 and checking the latest commit (with git log
or git rev-parse HEAD
)git log
或git rev-parse HEAD
)看到的相同git ls-tree HEAD
shows the target status , which is not necessarily the current one. git ls-tree HEAD
显示目标状态,不一定是当前状态。 If you want to update your submodules so that they correspond to the specified version, you have to use git submodule update
.git submodule update
。 What can cause the current and target status to differ?什么会导致当前状态和目标状态不同?
The typical situation in which they differ is when you git checkout
another branch/tag/commit, or you use git pull
to update your current branch.它们不同的典型情况是当您
git checkout
另一个分支/标签/提交时,或者您使用git pull
来更新您当前的分支。 Both these commands will cause HEAD
to be updated to the corresponding commit.这两个命令都会导致
HEAD
更新为相应的提交。 Now, if this commit specifies that your submodule has to use a different version, git submodule status
will still show the old one, but the target shown by git ls-tree HEAD
will already be the new one.现在,如果此提交指定您的子模块必须使用不同的版本,
git submodule status
仍将显示旧版本,但git ls-tree HEAD
显示的目标已经是新版本。
Is there a simpler way of noticing that they are out of sync?有没有更简单的方法来注意到它们不同步?
Check the output of git submodule status
.检查
git submodule status
的输出。 As the manual explains , if there's a +
before the hash, it means that the currently checked-out version and the target one are different. 正如手册所解释的那样,如果哈希之前有一个
+
,则表示当前签出的版本和目标版本不同。
How do I bring them back in sync?如何使它们恢复同步?
By running git submodule update
: the new submodule will be loaded, and both commands will indicate the same commit.通过运行
git submodule update
:将加载新的子模块,并且两个命令将指示相同的提交。
For example, let's say that in our repo we have a submodule called base
.例如,假设在我们的 repo 中有一个名为
base
的子模块。
The output of git submodule status
is (notice the +
): git submodule status
的输出是(注意+
):
+059ca6c4940813aa956e8668cb0af27efa189b22 base (release-1.2)
+059ca6c4940813aa956e8668cb0af27efa189b22 基础(1.2 版)
And the output of git ls-tree HEAD
is git ls-tree HEAD
的输出是
160000 commit fbc447ef9468def36cf4089094d6960cc51618b3 base
160000 提交 fbc447ef9468def36cf4089094d6960cc51618b3 基础
As we can see, the hashes are different.正如我们所看到的,哈希值是不同的。 In fact, the
+
had already informed us.事实上,
+
已经通知我们了。
Now, if we type git submodule update
, it says:现在,如果我们输入
git submodule update
,它会说:
Submodule path 'base': checked out 'fbc447ef9468def36cf4089094d6960cc51618b3'
子模块路径'base':签出'fbc447ef9468def36cf4089094d6960cc51618b3'
And now all the commands we can use ( git submodule status
, git ls-tree HEAD
, and git log
from inside base
) indicate fbc447ef9468def36cf4089094d6960cc51618b3
, and there's no +
in front of it in the output of git submodule status
.现在我们可以使用的所有命令(
git submodule status
, git ls-tree HEAD
和git log
from inside base
)都表示fbc447ef9468def36cf4089094d6960cc51618b3
,并且在git submodule status
的输出中前面没有+
。 If we run git submodule update
again, nothing happens, as everything is already up to date, and there isn't even any output.如果我们再次运行
git submodule update
,什么都不会发生,因为一切都已经是最新的,甚至没有任何输出。
1 : You have to be careful when you check the commit of a submodule, because it's tricky: to find the last commit that was made in submodule base
you can't use git log base
, you have to enter that directory ( cd base
) and then run git log
from there. 1 :检查子模块的提交时必须小心,因为它很棘手:要找到在子模块
base
中进行的最后一次提交,您不能使用git log base
,您必须进入该目录( cd base
)然后从那里运行git log
。 The reason is that the first command lists the commits of the "main" repository which set a new version of the submodule, and these commits are completely independent from those that were made inside the submodule.原因是第一个命令列出了设置子模块新版本的“主”存储库的提交,这些提交完全独立于子模块内部的提交。
更直接的命令是:
git submodule status
Sure;当然; there are several ways:
有几种方法:
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>
The first is easiest by far for checking a single submodule.第一个是迄今为止检查单个子模块最简单的方法。
The second/third is easiest if you want to check several submodules contained in the same directory, but you don't want to recurse into any other subdirectories that are not submodules.如果要检查同一目录中包含的多个子模块,第二个/第三个是最简单的,但您不想递归到任何其他不是子模块的子目录。 (The
:
syntax uses the top level of the repository as its reference point by default, rather than your current working directory, so be sure to include the ./
prefix if you're way in the depths of your repo right now.) (
:
语法默认使用存储库的顶层作为其参考点,而不是您当前的工作目录,因此如果您现在正处于 repo 的深处,请务必包含./
前缀。)
The fourth is easiest if you have a lot of submodules, and only submodules, in a single directory.如果您在一个目录中有很多子模块,并且只有子模块,那么第四个是最简单的。
Examples:例子:
git ls-tree HEAD src/thirdparty/libfoo
shows the submodule and nothing else. git ls-tree HEAD src/thirdparty/libfoo
显示子模块,仅此而已。git ls-tree HEAD:src/thirdparty
gives you everything directly below src/thirdparty
, including your submodule src/thirdparty/libfoo
. git ls-tree HEAD:src/thirdparty
为您提供src/thirdparty
/thirdparty 正下方的所有内容,包括您的子模块src/thirdparty/libfoo
。git ls-tree -r HEAD src/thirdparty
gives you everything directly below src/thirdparty
, including your submodule src/thirdparty/libfoo
, but will also recurse into src/thirdparty/docs
which is actually a regular directory in your repo. git ls-tree -r HEAD src/thirdparty
为您提供src/thirdparty
/thirdparty 正下方的所有内容,包括您的子模块src/thirdparty/libfoo
,但也会递归到src/thirdparty/docs
这实际上是您的回购中的常规目录。git ls-tree -r HEAD
lists absolutely everything in your repo, including submodules. git ls-tree -r HEAD
绝对列出你的 repo 中的所有内容,包括子模块。 Submodules will show up as type commit
(as opposed to the usual blob
or tree
).子模块将显示为类型
commit
(而不是通常的blob
或tree
)。
Pardon for lurking, but I believe the answer to the original question is likely to be:请原谅潜伏,但我相信原始问题的答案很可能是:
git submodule status --cached
"git submodule status" tells you which commit is checked out "--cached" tells you which commit a "git submodule update" would checkout. “git submodule status”告诉你哪个提交被签出“--cached”告诉你哪个提交“git submodule update”会签出。
I'm not sure when --cached was added to git.我不确定 --cached 何时添加到 git。
git ls-tree -r <submodule-commitID-of-interest> <submodule-path> | awk '{print $3}'
这里是打印子模块的 repo 提交 ID 的bash
行,最后 10 个子模块的提交 ID 指向:
git --no-pager log -10 --pretty="%H" <submodule-path> | while read i; do git ls-tree -r $I <submodule-path> | awk '{print $3}'; done
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.