我如何获得`git clone --recursive`来重新创建子模块的远程和分支? [英] How do I get `git clone --recursive` to recreate submodules' remotes and branches?

查看:186
本文介绍了我如何获得`git clone --recursive`来重新创建子模块的远程和分支?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个子模块的项目。他们中的很多人都是从GitHub fork中克隆的,我为其自定义的mod添加了一个分支。一个典型的设置就像这样:

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

  $ git branch -vva 
* my-fork 123456 [my-fork / my-fork]来自fork的最新提交信息
master abcdef [origin / master] repo
remotes / my-fork / my-fork 123456 [my-fork / my-fork]最新的提交msg来自fork
remotes / my-fork / master abcdef [origin / master]原始回购
remotes / origin / HEAD - >原产地/主产地
遥控器/产地/主产地abcdef [原产地/主产地]最初从原始回购提交的消息

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

我的项目开始一个新的分拆项目,当它开始递归时,它吐出一个错误,声称它找不到存储的提交为这些回购。在检查后,似乎没有添加远程控制器,并且分支在主控制器中留空(空)...

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

  $ git分支-vva 
* master abcdef [origin / master]最初的提交msg from original repo
remotes / origin / HEAD - >原产地/大师
遥控器/原产地/主控制器abcdef [原产地/主控制器]最初从原始回购提交信息

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

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



在上面有两个追踪分支但只有一个远程(origin =>我的github fork)的情况。在这种情况下,它发现提交并检查出来,但未能重新创建跟踪分支,从而留下悬挂提交...非常可怕,因为它不会警告您!

如何克隆我的项目,以便它可靠地重新创建子模块的远程和分支? 解决方案

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



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

< blockquote>

更新已注册的子模块,即克隆缺少的子模块并检出包含存储库索引中指定的提交。

这会使子模块HEAD被分离


2012:所以找不到活动分支在子模块是常态。

A git 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 ,都不记录在父回购中。

因此,当您再次克隆该父回购时,它将初始化并更新记录在 .gitmodules 文件中的子模块(您可以更改该地址,但只有一个与每个子模块相关联)。
如果您有其他远程地址与每个子模块关联,您需要一个脚本来自动执行该过程。 正如真性质的子模块,子模块主要是记录/访问历史中的一个固定点。

您可以直接在子模块内开发,但您需要去那里并做出正确的分支和/或添加正确的分支


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


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


  • 将它推送到关联的远程(即,记录在父回购的 .gitmodules 中的那个)

  • 返回到父母回购和提交所述父母。



但是:

如果您有推到' my-fork ',而该子模块的关联远程仓库是 not ' my-fork '...那么下一个克隆将无法检出该子模块提交。






更新2014年8月(Git 2.1)

请参阅提交9393ae7 通过 Matthew Chen( charlesmchen
$ b

子模块:文档 sync --recursive




git子模块同步命令支持 - 递归标志,但文档没有提及这一点。

该标志很有用,例如,当子模块的子模块中的远程变化时。



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:

In local folder: 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. 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/

$ 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!

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.

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

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.

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.


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

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 .gitmodules file (you can change that address, but only one is associated with each submodules).
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)
  • 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.


Update August 2014 (Git 2.1)

See commit 9393ae7 by Matthew Chen (charlesmchen):

submodule: document "sync --recursive"

The "git submodule sync" command supports the --recursive flag, 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 clone --recursive`来重新创建子模块的远程和分支?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆