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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10666085/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 06:56:22  来源:igfitidea点击:

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

gitgit-submodulesgit-clonecloninggit-remote

提问by Hari Karam Singh

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. A typical setup is like thus:

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

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                        [email protected]:MyUser/SomeAmazingRepo.git (fetch)
my-fork                        [email protected]:MyUser/SomeAmazingRepo.git (push)
origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (fetch)
origin                         git://github.com/OriginalOwner/SomeAmazingRepo.git (push)

I git clone --recursivemy 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. Upon inspection it seems that the remotes haven't been added and the branch is left (empty) in master ...

git clone --recursive我的项目开始一个新的分拆计划,当它开始递归,它吐出了一个错误,声称它找不到这些回购存储的提交。经过检查,似乎没有添加遥控器,并且分支在 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). 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!

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

How do I clone my project so that it reliably recreates the submodules' remotes and branches?

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

回答by VonC

git clone --recursiveis equivalent to git submodule update --init --recursive.

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

And a git submodule updatewill only checkout the recorded SHA1 (recorded in the parent repo):

并且git submodule update只会检出记录的 SHA1(记录在父仓库中):

Update the registered submodules, i.e. 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.
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.

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



2013-2014: you can configure your .gitmodulesfile in order to specify a branch to checkout in your submodule.
See "How do I update my git submodules from specific branches?"

2013-2014:您可以配置您的.gitmodules文件,以便在您的子模块中指定要结帐的分支
请参阅“如何从特定分支更新我的 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.
So when you clone again that parent repo, it will initialize and update the submodules as recorded in the .gitmodulesfile (you can change that address, but only oneis associated with each submodules).
If you have other remote address to associate to each submodule, you need a script to automate the process.

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

As explained in "True nature of submodule", a submodule is primarily there to record/access a fixedpoint 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 .gitmodulesof the parent repo)
  • go back to the parent repo and commit said parent.
  • 将其推送到关联的远程(即记录在.gitmodules父仓库中的那个)
  • 返回父仓库并提交所述父项。

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 9393ae7by Matthew Chen (charlesmchen):

提交9393ae7马修·陈(charlesmchen

submodule: document "sync --recursive"

子模块:文档“ sync --recursive

The "git submodule sync" command supports the --recursiveflag, but the documentation does not mention this.
That flag is useful, for example when a remote is changed in a submodule of a submodule.

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



Update Git 2.23 (Q3 2019)

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

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 父存储库 SHA1 进行克隆。