如何在git中添加现有的子存储库作为子模块?
我有一个私有的codespace
超级模块,子模块是随机分散的:
codespace (git repo, private)
├── Archived_projects (git repos)
└── Projects
├── project-foo (git repo)
└── project-bar (git repo)
有时子模块的提交尚未准备好被推送。但我希望他们在推动超模codespace
时得到保存
codespace
是克隆到c9.io工作区或其他地方的回购邮件。
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 .
来自 cmd.exe
> 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
来自 cygwin.exe (bash)
$ 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
git submodule [--quiet] add [-b <branch>] [-f|--force] [--name <name>]
[--reference <repository>] [--depth <depth>] [--] <repository> [<path>]
<repository> is the URL of the new submodule’s origin repository.
<path> is the relative location for the cloned submodule to exist in the superproject. If <path> does not exist, then the
submodule is created by cloning from the named URL. If <path> does exist and is already a valid Git repository, then this is
added to the changeset without cloning. This second form is provided to ease creating a new submodule from scratch, and
presumes the user will later push the submodule to the given URL.
In either case, the given URL is recorded into .gitmodules for use by subsequent users cloning the superproject. If the URL
is given relative to the superproject’s repository, the presumption is the superproject and submodule repositories will be
kept together in the same relative location, and only the superproject’s URL needs to be provided: git-submodule will
correctly locate the submodule using the relative URL in .gitmodules.
如果<path>
确实存在且已经是有效的Git存储库,则会将其添加到变更集而不进行克隆。
为什么这在我的情况下不起作用?
答案 0 :(得分:8)
你做错了什么地方
$ git add .
这会将所有内容(foo/bar
)也添加到当前存储库的索引中(准备提交)。
如果您不这样做,请继续
$ git submodule add https://github.com/CarloWood/XYZ.git foo/bar
然后应该起作用;这将检测到foo / bar已被克隆 存储库,并将其作为子模块添加到当前存储库中。
请注意,不需要先克隆。您明确地说您已经这样做了,但是为了其他读者清楚起见,我想指出的是,如果您也在git add .
之前也省略了克隆(因此现在完全没有foo / bar了) ),那么上面的git submodule add ...
会看到还没有任何东西,然后简单地为您克隆它。
请注意,方法之间存在微小差异。如果您从克隆开始,那么foo/.git
将是一个目录,而如果您使用git submodule add
进行克隆,则此.git
存储库将放在父项目的.git/modules/foo
中,并且foo/.git
是包含该文件路径的文件。但是并没有真正的区别,因为使用.git
文件指向其他任何地方都是通用的,可以在任何地方使用。您无法从.git
作为文件或目录得出任何结论。
答案 1 :(得分:2)
foo/bar
中删除文件:git rm -f --cached foo/bar
git submodule add https://github.com/octocat/Spoon-Knife.git ./foo/bar
答案 2 :(得分:1)
git submodule add
会检测为子宏指定的路径是否存在,并包含已初始化的git repo,因此无需担心。我遇到了类似的问题,所以我写了一个(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
答案 3 :(得分:1)
为现有存储库增加 Carlos Answer。它已经包含它的 URL。你可以简单地
git submodule add $(cat repodir/.git/config | grep url | cut -d '=' -f 2) reponame
答案 4 :(得分:0)
一种方法是手动创建.gitmodule
文件
格式如下
[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
答案 5 :(得分:-1)
您不需要先手动克隆。运行git submodule add [url] [path]
运行git submodule update
后,将为您克隆/拉出所有子模块。