git 子模块签出相同的提交

git submodule checks out the same commit

在我 git submodule update 之后它总是检出相同的提交。例如 34561.

我为子模块做 git checkout master,然后 git submodule sync。然后它指向最新的提交 a2344.

但在 update 之后它再次指向提交 34561.

怎么改?我的意思是为什么它决定指向那个提交而不是另一个?

您需要进入子模块文件夹并执行:

git fetch --all --prune
git pull origin master

现在您将在子模块中获得最新的提交。
一旦你 运行 获取它的更新你的 .git 文件夹下的子模块与最新的提交。它将确保您拥有最近的更改。

您可以执行:

git submodule foreach git pull origin master

这将更新您的所有子模块。

I mean why it decided to point to that commit and not another?

因为子模块总是在父仓库中记录一个固定的 SHA1 提交作为 gitlink (a special entry in the index).
这就是为什么子模块总是恢复为 detached HEAD branch

您可以配置一个子模块跟随一个分支

cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>

子模块仍将恢复到固定提交,但随后可以更新为:

git submodule update --remote

确保在父仓库中添加并提交新的 gitlink(因为将子模块更新到分支的最新版本会更改其 SHA1,在父仓库中记录为一个 gitlink).
如果不这样做,您将在下一个 git submodule update --init.

处发现您的子模块恢复到之前的状态

在“Git submodules: Specify a branch/tag”查看更多信息。

'main' 项目包含对每个子模块签出版本的 SHA-1 的引用。这是主项目中提交的一部分。

如果您在子模块中手动更改子模块的头部,您需要告诉主项目从现在开始它应该为子模块使用这个SHA-1。

git commit -a

会这样做,因为主项目会看到子模块头已更新。

这可能令人惊讶,但它实际上是一个不错的功能。通过检查主项目的头部,您基本上告诉您的同事现在可以使用子模块的较新版本了。这使人们可以一起工作,而不会冒太大的冒犯别人的风险。

(话虽这么说,带有子模块的工作流中有很多缺点,您可能应该同意一种方法并将其与一些团队脚本结合起来以避免陷阱)。