如何让`git clone --recursive`重新创建子模块的遥控器和分支?

Har*_*ngh 16 git cloning git-clone git-remote git-submodules

我有一个带有一些子模块的项目.其中许多是从GitHub fork中克隆到的,我为自定义mod添加了一个分支.典型的设置如下:

在本地文件夹中: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)
Run Code Online (Sandbox Code Playgroud)

git clone --recursive我的项目开始一个新的分拆计划,当它开始递归,它吐出了一个错误,声称它找不到这些回购存储的提交.检查后,似乎没有添加遥控器,并且分支机构在主机中留下(空)...

在本地文件夹中: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)
Run Code Online (Sandbox Code Playgroud)

唯一的补救措施是手动将遥控器添加到所有回购(非常繁琐).

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

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

Von*_*onC 25

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

并且git子模块更新将仅检出记录的SHA1(记录在父仓库中):

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

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


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

cd /path/to/your/parent/repo
git config -f .gitmodules submodule.<path>.branch <branch>
Run Code Online (Sandbox Code Playgroud)

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

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

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

每次在子模块中进行提交时,都需要:

  • 将它推送到相关的遥控器(即,.gitmodules在父级回购中记录的遥控器)
  • 回到父回购并提交父母.

但:

如果你已经推送到' my-fork'而该子模块的相关远程仓库不是 ' my-fork'...那么下一个克隆将无法检查该子模块提交.


2014年8月更新(Git 2.1)

提交9393ae7马修·陈(charlesmchen):

子模块:文件" sync --recursive"

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