18

我有一个包含几个子模块的项目。其中许多是从 GitHub fork 克隆的,我为我的自定义模块添加了一个分支。一个典型的设置是这样的:

在本地文件夹中:MyProject1/Frameworks/SomeAmazingRepo/

$ git branch -vva
*my-fork                       123456 [my-fork/my-fork] Latest commit msg from fork
master                         abcdef [origin/master] Latest commit msg from original repo
remotes/my-fork/my-fork        123456 [my-fork/my-fork] Latest commit msg from fork
remotes/my-fork/master         abcdef [origin/master] Latest commit msg from original repo
remotes/origin/HEAD            -> origin/master
remotes/origin/master          abcdef [origin/master] Latest commit msg from original repo

$ git remote -v
my-fork                        git@github.com:MyUser/SomeAmazingRepo.git (fetch)
my-fork                        git@github.com:MyUser/SomeAmazingRepo.git (push)
origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (fetch)
origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (push)

git clone --recursive的项目开始一个新的衍生项目,当它开始递归时,它会吐出一个错误,声称它找不到这些存储库的存储提交。经检查,似乎没有添加遥控器,并且分支在 master ...

在本地文件夹中:MyProject2/Frameworks/SomeAmazingRepo/

$ git branch -vva
*master                        abcdef [origin/master] Latest commit msg from original repo
remotes/origin/HEAD            -> origin/master
remotes/origin/master          abcdef [origin/master] Latest commit msg from original repo

$ git remote -v
origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (fetch)
origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (push)

唯一的补救措施是手动将遥控器添加到所有存储库(非常乏味)。

在上面有两个跟踪分支但只有一个远程(origin => my github fork)的情况下存在类似的问题。在这种情况下,它会找到提交并检查它,但无法重新创建跟踪分支,留下一个“悬空”提交......非常可怕,因为它没有警告你!

如何克隆我的项目,以便它可靠地重新创建子模块的遥控器和分支?

4

1 回答 1

30

git clone --recursive相当于git submodule update --init --recursive

并且git 子模块更新只会签出记录的 SHA1(记录在父 repo 中):

更新已注册的子模块,即克隆缺少的子模块并签出包含存储库的索引中指定的提交。
这将使子模块 HEAD 分离

2012:因此在子模块中找不到活动分支是常态。
Agit submodule foreach 'git checkout master'至少可以设置主分支(如果您确定所有记录的 SHA1 都应该是每个子模块的“主”分支的一部分。


2013-2014:您可以配置.gitmodules文件以在子模块中指定要结帐的分支
请参阅“如何从特定分支更新我的 git 子模块?

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

您在子模块中本地添加的任何远程,例如my-fork,根本不会记录在父存储库中。
因此,当您再次克隆该父 repo 时,它将初始化和更新.gitmodules文件中记录的子模块(您可以更改该地址,但每个子模块只有一个关联)。
如果您有其他远程地址要关联到每个子模块,则需要一个脚本来自动化该过程。

如“子模块的真实性质”中所述,子模块主要用于记录/访问历史中的固定点。
您可以直接在子模块中开发,但您需要去那里创建正确的分支和/或添加正确的遥控器。

它吐出一个错误,声称找不到这些存储库的存储提交。

每次在子模块中提交时,您需要:

  • 将其推送到关联的远程(即记录在.gitmodules父仓库中的远程)
  • 返回父回购并提交所述父。

但:

如果您在my-fork该子模块的关联远程仓库不是“ ”时推送到“ my-fork”...那么下一个克隆将无法签出该子模块提交。


2014 年 8 月更新 (Git 2.1)

请参阅Matthew Chen ( )提交 9393ae7charlesmchen

子模块:文档“ sync --recursive

" git submodule sync" 命令支持该--recursive标志,但文档没有提及这一点。
该标志很有用,例如当远程在子模块的子模块中更改时。


更新 Git 2.23(2019 年第三季度)

您还可以考虑git clone --recurse-submodule --remote-submodules:这将使用已在其跟踪分支而不是其 gitlink 父 repo SHA1 签出的子模块进行克隆。

于 2012-07-12T12:20:15.023 回答