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

时间:2012-05-19 14:34:38

标签: git git-submodules git-clone cloning git-remote

我有一个包含少量子模块的项目。其中许多是从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)

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)

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

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

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

1 个答案:

答案 0 :(得分:25)

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

git submodule update只会检出记录的SHA1(记录在父回购中):

  

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

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


2013-2014:您可以配置.gitmodules文件,以指定要在子模块中结帐的分支
请参阅“How do I update my git submodules from specific branches?

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

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

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

  

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

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

  • 将其推送到关联的远程(即父回购的.gitmodules中记录的远程)
  • 回到父回购并提交父母。

可是:

如果你已经推送到'my-fork',而该子模块的关联远程仓库'my-fork'...则下一个克隆将不会能够检查子模块提交。


2014年8月更新(Git 2.1)

commit 9393ae7Matthew Chen (charlesmchen)

子模块:文档“sync --recursive

  

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