简体   繁体   English

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

[英]How do I get `git clone --recursive` to recreate submodules' remotes and branches?

I have a project with a handful of submodules. 我有一个带有一些子模块的项目。 Many of them are cloned from a GitHub fork to which I've added a branch for my custom mods. 其中许多是从GitHub fork中克隆到的,我为自定义mod添加了一个分支。 A typical setup is like thus: 典型的设置如下:

In local folder: MyProject1/Frameworks/SomeAmazingRepo/ 在本地文件夹中: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)

I git clone --recursive my project to begin a new spin-off project and when it begins to recurse, it spits out an error claiming it can't find the stored commits for these repos. git clone --recursive我的项目开始一个新的衍生项目,当它开始递归时,它吐出一个错误,声称它无法找到这些回购的存储提交。 Upon inspection it seems that the remotes haven't been added and the branch is left (empty) in master ... 检查后,似乎没有添加遥控器,并且分支机构在主机中留下(空)...

In local folder: MyProject2/Frameworks/SomeAmazingRepo/ 在本地文件夹中: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)

The only remedy is to go and add the remotes manually to all the repos (very tedious). 唯一的补救措施是手动将遥控器添加到所有回购(非常繁琐)。

There exists a similar issue in the cases where there are two tracking branches as above but only one remote (origin => my github fork). 在上面有两个跟踪分支但只有一个远程(origin => my github fork)的情况下存在类似的问题。 In these case, it finds the commit and checks it out but fails to recreate the tracking branch, leaving a "dangling" commit...very scary as it doesn't warn you! 在这种情况下,它找到提交并检查它但无法重新创建跟踪分支,留下“悬空”提交......非常可怕,因为它不会警告你!

How do I clone my project so that it reliably recreates the submodules' remotes and branches? 如何克隆我的项目,以便可靠地重新创建子模块的遥控器和分支?

git clone --recursive is equivalent to git submodule update --init --recursive . git clone --recursive相当于git submodule update --init --recursive

And a git submodule update will only checkout the recorded SHA1 (recorded in the parent repo): 并且git子模块更新将仅检出记录的SHA1(记录在父仓库中):

Update the registered submodules, ie clone missing submodules and checkout the commit specified in the index of the containing repository. 更新已注册的子模块,即克隆缺少的子模块,并检查包含的存储库索引中指定的提交。
This will make the submodules HEAD be detached . 这将使子模块HEAD分离

2012: So finding no active branch in a submodule is the norm. 2012:因此在子模块中找不到活动分支是常态。
A git submodule foreach 'git checkout master' can at least set the master branch (if you are sure that all the recorded SHA1 were supposed to be part of a 'master' branch for each submodules. 一个git submodule foreach 'git checkout master'至少可以设置master分支(如果你确定所有记录的SHA1都应该是每个子模块的'master'分支的一部分。


2013-2014: you can configure your .gitmodules file in order to specify a branch to checkout in your submodule . 2013-2014: 您可以配置.gitmodules文件,以指定要在子模块中签出的分支
See " How do I update my git submodules from specific branches? " 请参阅“ 如何从特定分支更新我的git子模块?

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

Any remote that you add locally in a submodule, like my-fork , aren't recorded in the parent repo at all. 您在子模块中本地添加的任何远程数据库(如my-fork )根本不会记录在父存储库中。
So when you clone again that parent repo, it will initialize and update the submodules as recorded in the .gitmodules file (you can change that address , but only one is associated with each submodules). 因此,当您再次克隆该父repo时,它将初始化并更新.gitmodules文件中记录的子模块(您可以更改该地址 ,但只有一个与每个子模块相关联)。
If you have other remote address to associate to each submodule, you need a script to automate the process. 如果您有其他远程地址与每个子模块关联,则需要一个脚本来自动执行该过程。

As explained in " True nature of submodule ", a submodule is primarily there to record/access a fixed point in the history. 如“ 子模块的真实性质 ”中所述,子模块主要用于记录/访问历史中的固定点。
You can develop directly within a submodule, but you need to go there and make the right branch and/or add the right remotes. 您可以直接在子模块中进行开发,但是您需要去那里制作正确的分支和/或添加正确的遥控器。

it spits out an error claiming it can't find the stored commits for these repos. 它吐出一个错误,声称它无法找到这些存储库的存储提交。

Every time you make a commit in a submodule, you need to: 每次在子模块中进行提交时,都需要:

  • push it to the associated remote (ie, the one recorded in the .gitmodules of the parent repo) 将它推送到相关的遥控器(即父级回购的.gitmodules中记录的遥控器)
  • go back to the parent repo and commit said parent. 回到父回购并提交父母。

But: 但:

If you have pushed to ' my-fork ' while the associated remote repo of that submodule was not ' my-fork '... then the next clone won't be able to checkout that submodule commit. 如果你已经推送到' my-fork '而该子模块的相关远程仓库不是 ' my-fork '...那么下一个克隆将无法检查该子模块提交。


Update August 2014 (Git 2.1) 2014年8月更新(Git 2.1)

See commit 9393ae7 by Matthew Chen ( charlesmchen ) : Matthew Chen( charlesmchen 提交的9393ae7

submodule: document " sync --recursive " 子模块:文件“ sync --recursive

The " git submodule sync " command supports the --recursive flag, but the documentation does not mention this. git submodule sync ”命令支持--recursive标志,但文档没有提到这一点。
That flag is useful, for example when a remote is changed in a submodule of a submodule. 该标志很有用,例如当在子模块的子模块中更改远程时。


Update Git 2.23 (Q3 2019) 更新Git 2.23(2019年第3季度)

You can also consider git clone --recurse-submodule --remote-submodules : that will clone with submodules already checked out at their tracking branch instead of their gitlink parent repo SHA1. 您还可以考虑使用git clone --recurse-submodule --remote-submodules :将使用已在其跟踪分支中检出的子模块而不是其gitlink父repo SHA1进行克隆。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM