将子模块更新至最新提交

436

我有一个名为A的项目,它是一个库,并且被另一个名为B的项目使用。

A和B都在Github上拥有单独的代码库,但在B中我们嵌套了一个A的子模块。

我编辑了库中一些类(存储于A代码库),并将其推送到远程代码库,因此库(A代码库)已经更新。

这些更新不会反映在“引用”(即子模块)上,该子模块指向之前的提交.... 我该怎么做才能在git上更新子模块?


4
首先执行命令git submodule update --remote --merge,确保子模块指向最新的哈希值(在 git 1.8之后有效)。然后通过提交子模块来提交指向新哈希值的指针:git add proj/submodule ,然后执行 git commit -m 'adding new submodule'。我最喜欢的答案是这个:https://dev59.com/vGsy5IYBdhLWcg3w-i7h#42175412 - Charlie Parker
9个回答

556

进入子模块目录:

cd projB/projA

从项目A中拉取代码库(不会更新父级项目B的Git状态):

git pull origin master

回到根目录并检查更新:

cd ..
git status
如果子模块之前已经更新过,它将显示类似以下的内容:
# Not currently on any branch.
# Changed but not updated:
#   (use "git add ..." to update what will be committed)
#   (use "git checkout -- ..." to discard changes in working directory)
#
#       modified:   projB/projA (new commits)
#

然后,提交更新:

git add projB/projA
git commit -m "projA submodule updated"

更新

正如@paul所指出的那样,自Git 1.8以来我们可以使用以下命令:

git submodule update --remote --merge

更新子模块到最新的远程提交。在大多数情况下都很方便。


43
顺便提一下,如果你不是子模块的所有者,当其他人更新了projA(你会得到一个新的提交ID),你只需要执行 git submodule update - Kjuly
@Kjuly 提交代码后,如何将其推送到远程存储库?仅需要执行 git push 命令吗? - KR29
2
@KR29 没错,完整的命令是 git push <remote> <branch>,例如 git push origin dev - Kjuly
3
git submodule update 只有在拉取了一个更新子模块引用的提交(在项目 B 中),才能在没有标志的情况下工作(在项目 A 中)。要将项目 B 更新为引用项目 A 远程跟踪分支的 HEAD,您需要执行 git submodule update --remote --merge,如 Paul Hatcher 在下面的回答中所示。 - Ben Burns
4
仅更新一个子模块:git submodule update --remote --merge <path-to-submodule> - ko80
显示剩余9条评论

197

自 Git 1.8 版本以来,您可以执行以下操作:

git submodule update --remote --merge

这将更新子模块到最新的远程提交。然后,您需要添加并提交更改,以便在父存储库中更新gitlink:

首先,使用 git add 命令添加它。

git add project/submodule_proj_name

然后进行 git commit 操作

git commit -m 'gitlink to submodule_proj_name was updated'

推送 git

git push

如果不这样做,指向子模块的SHA-1标识将无法更新,因此更改对其他人来说将不可见。


1
即使我执行了 git commit,其他人仍然看不到它。 在主分支上 您的分支已经是 'origin/master' 的最新版本。 未提交的更改: 修改:SubmoduleA(新提交) 修改:SubmoduleB(新提交) - Max N
1
你在提交(commit)代码后,是否执行了"git push"命令?请注意,提交(commit)只是更改本地代码库,你必须将其推送(push)到远程代码库,以便其他人可以看到它。 - Paul Hatcher
3
这个答案中缺少的是(但在下面的其他答案中已经提到):更新的子模块需要在提交之前使用 git add 进行暂存。 - joshng
1
@joshng 我认为每个正在处理子模块的人都能理解这一点。这是唯一帮助了我很多的帖子,非常感谢。 - Husk Rekoms

50
如果您更新了一个子模块并提交了更改,那么您需要转到包含或更高级别的代码库,并在那里添加该更改。
git status

将显示类似于:

modified:
   some/path/to/your/submodule

可以通过以下方式看出子模块是否未同步:

git submodule

输出结果将显示:

+afafaffa232452362634243523 some/path/to/your/submodule

加号表示你的子模块指向了比顶层仓库预期的更靠前的位置。

只需添加此更改:

git add some/path/to/your/submodule

并提交它:

git commit -m "referenced newer version of my submodule"

当您推送更改时,请确保您先推送子模块中的更改,然后再将外部仓库的引用更改推送上去。这样,更新的人始终能够成功运行。

git submodule update

有关子模块的更多信息可以在此处查找 http://progit.org/book/ch6-6.html


如果在运行 git submodule 时没有看到 +,请确保已经初始化并导入了子模块。分别使用 git submodule initgit submodule update 命令进行操作。 - fureigh

23

单行版本

git submodule foreach "(git checkout master; git pull; cd ..; git add '$path'; git commit -m 'Submodule Sync')"

7

解决方案一

为了简化操作,运行以下命令获取子模块的最新版本:

git submodule update --remote --merge

or 

git submodule update --remote

现在,我们需要更新父代码库中的引用,可以使用以下命令完成:
git add <<submodulesfoldername>>

注意: <> == 我的子模块文件夹名称 git add sub-modules (记得使用代码提交和推送,最新提交的引用将被添加)

enter image description here

解决方案 2

如果上述解决方案不能拉取最新版本,请尝试以下方法:

git submodule update --init --recursive

6

以上答案都不能解决我的问题。

以下是解决方案,在上级目录下运行:

git submodule update --init;
cd submodule-directory;
git pull;
cd ..;
git add submodule-directory;

现在你可以通过执行 git commitgit push 来提交代码。


你的答案与之前的相似,只是有一点不同:添加子模块有时不会指向分支,因此你不需要在每次修改时都添加子模块。 - JRichardsz

4

其他一些答案建议在子模块目录内进行合并/提交操作,但我认为这可能会变得有点凌乱。

假设远程服务器的名称为origin,我们想要子模块的master分支,我倾向于使用:

git submodule foreach "git fetch && git reset --hard origin/master"

注意: 这将对每个子模块执行硬重置--如果您不希望这样,请将--hard更改为--soft


1
我的项目应该使用子模块的“latest”版本。在Mac OSX 10.11上,git版本为2.7.1,我不需要进入子模块文件夹来收集其提交记录。我只是正常地进行了一个。
git pull --rebase 

在顶层操作,它正确地更新了我的子模块。

0

Andy的回答对我有用,通过转义$path:

git submodule foreach "(git checkout master; git pull; cd ..; git add \$path; git commit -m 'Submodule Sync')"

@Andy Webov 的回答不需要转义的原因可能是因为他们在路径周围使用了单引号,例如 '$path' - S0AndS0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接