问题
如何在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储存机制,则会将其加入变更集而不进行复制。
为什么这在我的情况下不起作用?
8条答案
按热度按时间lsmd5eda1#
哪里出了问题
你做错的地方是
这会将所有内容,以及
foo/bar
,添加到当前仓库的索引中(准备提交)。正确的方式
如果你不这么做继续
那应该可以这将检测到foo/bar是一个已经克隆的存储库,并将其作为子模块添加到当前存储库中。
请注意,不需要首先克隆。您明确地说您已经做了克隆,但是为了让其他读者清楚起见,我想指出,如果您也省略了
git add .
前面的克隆(因此现在根本没有foo/bar),那么上面的git submodule add ...
将看到还没有任何内容,然后简单地为您克隆它。请注意,两种方法之间有一个小的区别。如果从克隆开始,那么
foo/.git
将是一个目录,而如果你使用git submodule add
来克隆,那么这个.git
存储库被放在父项目的.git/modules/foo
中,foo/.git
是一个包含路径的文件。然而,由于使用.git
的文件指向任何其他地方是通用的,并且可以在任何地方使用,因此没有真实的的区别;您不能从.git
推断出任何内容是文件或目录。h43kikqp2#
一种方法是手动创建
.gitmodules
文件。格式如下:
请注意,您必须运行
应用更改
5cnsuln73#
git submodule add
会检测submosule的路径是否存在,是否包含初始化的git repo,所以不用担心这个问题。我遇到过类似的问题,所以我写了一个(hacky)脚本来处理这个问题。wqnecbli4#
为现有的存储库增加卡洛斯Answer。它已经包含其URL。您可以简单地
wj8zmpe15#
不要使用
git add
添加子模块,使用git submodule add
如果您已经克隆了存储库,只需运行
NB:相对路径前缀
./
在这里很重要...除非您指定的是绝对路径。或者
如果项目使用相对URL。
biswetbf6#
1.从索引
foo/bar
中删除文件:git rm -f --cached foo/bar
git submodule add https://github.com/octocat/Spoon-Knife.git ./foo/bar
jgzswidk7#
至少,如果(未来的)子模块没有递归的其他仓库/.git目录,那么下面的代码只是简单地添加了所有这些目录。(我不知道为什么我必须在命令中提供目录作为路径和“repository”,但无论如何...)
disho6za8#
您不需要先手动克隆,运行
git submodule add [url] [path]
后再运行git submodule update
,它会为您克隆/拉取所有子模块。