如何`git submodule add`现有子存储库?

ily*_*rov 12 git git-submodules cloud9-ide

问题

如何将现有的子存储库添加为 git 中的子模块?

为什么

我有一个私人codespace超级模块,其子模块随机分散:

codespace (git repo, private)
??? Archived_projects (git repos)
??? Projects
    ??? project-foo (git repo)
    ??? project-bar (git repo)
Run Code Online (Sandbox Code Playgroud)

有时子模块有未准备好推送的提交。但我希望在推送 supermodule 时保存它们codespace
codespace是克隆到c9.io工作区或其他地方的 repo 。

我所做的

codespace (git repo, private)
??? Archived_projects (git repos)
??? Projects
    ??? project-foo (git repo)
    ??? project-bar (git repo)
Run Code Online (Sandbox Code Playgroud)

cmd.exe

linus@machine /cygdrive/f/__Storage__/Workspace
$ git clone https://github.com/octocat/Spoon-Knife.git
Cloning into 'Spoon-Knife'...
$ cd Spoon-Knife/
$ git clone https://github.com/octocat/Spoon-Knife.git ./foo/bar
Cloning into './foo/bar'...
$ git add .
Run Code Online (Sandbox Code Playgroud)

cygwin.exe (bash)

> git submodule add https://github.com/octocat/Spoon-Knife.git ./foo/bar
'foo/bar' already exists in the index
> cat .gitmodules
cat: .gitmodules: No such file or directory
Run Code Online (Sandbox Code Playgroud)

参考

$ git submodule add https://github.com/octocat/Spoon-Knife.git ./foo/bar
': not a valid identifier/Git/mingw64/bin/gettext.sh: line 89: export: `sm_path
'' already exists in the index
$ cat .gitmodules
cat: .gitmodules: No such file or directory
Run Code Online (Sandbox Code Playgroud)

如果<path>确实存在并且已经是有效的 Git 存储库,则将其添加到变更集中而不进行克隆。

为什么这在我的情况下不起作用?

Car*_*ood 19

你出错的地方是在做

$ git add .
Run Code Online (Sandbox Code Playgroud)

这将所有内容添加foo/bar到当前存储库的索引中(准备好提交)。

如果你只是不这样做并继续

$ git submodule add https://github.com/CarloWood/XYZ.git foo/bar
Run Code Online (Sandbox Code Playgroud)

那么这应该有效;这将检测到 foo/bar 是一个已经克隆的存储库,并将其作为子模块添加到当前存储库中。

请注意,不需要先克隆。你明确地说你已经这样做了,但为了让其他读者清楚起见,我想指出,如果你在之前省略了克隆git add .(所以现在根本没有 foo/bar)那么上面git submodule add ...会看到还没有任何东西,然后简单地为您克隆它。

请注意,方法之间存在细微差别。如果您从克隆开始,那么foo/.git它将是一个目录,而如果您git submodule add用来进行克隆,那么此.git存储库将放在.git/modules/foo父项目中,并且foo/.git是一个包含该路径的文件。但是没有真正的区别,因为使用文件.git指向其他任何地方都是通用的,可以在任何地方使用;你不能从.git文件或目录中得出任何结论。


Ruf*_*fus 10

一种方法是手动创建该.gitmodules文件。

格式如下:

[submodule "path/to/submodule1"]
    path = path/to/submodule/1
    url = git@github.com:user/submodule1
[submodule "path/to/submodule2"]
    path = path/to/submodule/2
    url = git@github.com:user/submodule2
Run Code Online (Sandbox Code Playgroud)

请注意,您必须运行

git submodule sync
Run Code Online (Sandbox Code Playgroud)

应用更改


小智 7

git submodule add检测为 submosule 指定的路径是否存在并包含初始化的 git 存储库,因此无需担心这一点。我遇到了类似的问题,所以我编写了一个(hacky)脚本来处理这个问题。

#!/bin/bash
# save super directory
currentDir=`pwd`
# get all the git repos inside (except .) and format them 
# the way git does
gitDirs=`find -type d -name ".git" | sed -e 's|.git$||' -e 's|./||' -e 's|/$||' | grep -v "^$"`

for i in ${gitDirs[@]}
do
        echo "dealing with $i now"

        cd $i 
        # get the remote url for each submodule
        fetchUrl=`git remote -v | awk '/fetch/ {print $2}'`
        # for my purposes repos without remotes are useless
        # but you may have a different use case
        if [[ -z $fetchUrl ]]
        then
                echo "fetch url not found for this directory"
                continue
        else                                                      
                echo "got a fetch url of $fetchUrl for git repo $i"                                                                 
        fi                                                        

        cd $currentDir
        # make sure it isn't tracked as a submodule already                                                         
        existing=`grep -A5  $i ./.gitmodules | grep $fetchUrl`    

        if [[ -z $existing ]]                                     
        then                                                      
                echo "does not exist in .gitmodules yet, will create now"
                # if it doesn't exist yet then create it
                git submodule add $fetchUrl $i
        else
                echo "$i is already present as a submodule with fetch url: $fetchUrl"
                echo "The command we would have used is: git submodule add $fetchUrl $i"
        fi
done

Run Code Online (Sandbox Code Playgroud)


Cer*_*vEd 5

不要使用 添加子模块git add,使用git submodule add

git submodule [--quiet] add [<options>] [--] <repository> [<path>]
Run Code Online (Sandbox Code Playgroud)

如果您已经克隆了存储库,只需运行

git submodule add -- "$(git -C ./sub/ remote get-url origin)" ./sub/
Run Code Online (Sandbox Code Playgroud)

注意:相对路径前缀./在这里很重要......除非您指定绝对路径。

或者

git submodule add -- ./sub.git ./sub
Run Code Online (Sandbox Code Playgroud)

如果项目使用相对 URL。


小智 -3

您不需要先手动克隆。运行git submodule add [url] [path]run后git submodule update,它将为您克隆/拉取所有子模块。