我有一个带有Git子模块的项目。它来自ssh://…URL,在提交a上,提交B已经被推到那个URL,我想让子模块检索提交,并更改它。

现在,我的理解是git子模块更新应该这样做,但它没有。它不做任何事情(没有输出,成功退出代码)。这里有一个例子:

$ mkdir foo
$ cd foo
$ git init .
Initialized empty Git repository in /.../foo/.git/
$ git submodule add ssh://user@host/git/mod mod
Cloning into mod...
user@host's password: hunter2
remote: Counting objects: 131, done.
remote: Compressing objects: 100% (115/115), done.
remote: Total 131 (delta 54), reused 0 (delta 0)
Receiving objects: 100% (131/131), 16.16 KiB, done.
Resolving deltas: 100% (54/54), done.
$ git commit -m "Hello world."
[master (root-commit) 565b235] Hello world.
 2 files changed, 4 insertions(+), 0 deletions(-)
 create mode 100644 .gitmodules
 create mode 160000 mod
# At this point, ssh://user@host/git/mod changes; submodule needs to change too.
$ git submodule init
Submodule 'mod' (ssh://user@host/git/mod) registered for path 'mod'
$ git submodule update
$ git submodule sync
Synchronizing submodule url for 'mod'
$ git submodule update
$ man git-submodule 
$ git submodule update --rebase
$ git submodule update
$ echo $?
0
$ git status
# On branch master
nothing to commit (working directory clean)
$ git submodule update mod
$ ...

我也尝试过git fetch mod,它似乎做了一个取回(但不可能,因为它不提示密码!),但git日志和git显示否认新提交的存在。到目前为止,我只是在rm-ing模块并重新添加它,但这在原则上是错误的,在实践中也很乏味。


当前回答

如果你不知道主机分支,这样做:

git submodule foreach git pull origin $(git rev-parse --abbrev-ref HEAD)

它将获得主Git存储库的一个分支,然后为每个子模块提取相同的分支。

其他回答

在我的例子中,我希望git更新到最新,同时重新填充任何丢失的文件。

下面恢复了丢失的文件(多亏了——force,这里似乎没有提到),但它没有拉出任何新的提交:

Git子模块update——init——recursive——force

这是:

Git子模块更新——递归——远程——合并——强制

如果你想为每个子模块签出主分支,你可以使用下面的命令:

git submodule foreach git checkout master

这里有一个很棒的一行代码,可以将所有内容更新到master上的最新版本:

git submodule foreach 'git fetch origin --tags; git checkout master; git pull' && git pull && git submodule update --init --recursive

感谢Mark Jaquith

在你的项目父目录下,运行:

git submodule update --init

或者如果你有递归子模块运行:

git submodule update --init --recursive

有时这仍然不起作用,因为在更新子模块时,在本地子模块目录中有本地更改。

大多数情况下,本地更改可能不是您想要提交的更改。这可能是由于子模块中的文件删除等原因造成的。如果是这样,在你的本地子模块目录和你的项目父目录中重置,再次运行:

git submodule update --init --recursive

对我来说,所有的git子模块都不工作。但这个方法奏效了:

cd <path/to/submodule>
git pull

它下载并因此更新第三方回购。 然后

cd <path/to/repo>
git commit -m "update latest version" <relative_path/to/submodule>
git push

它更新了您的远程回购(与最后一次提交的链接repo@xxxxxx)。