Git:创建子模块作为存储库

20

我想将一个新仓库创建为我的项目的子模块。

通常,我会先在 Github 上创建一个仓库,然后使用命令 git submodule add url_to_repo.git 将其作为子模块添加。

有没有一种方法可以直接创建一个新的仓库作为子模块,而不需要事先在其他地方创建该仓库(无论是本地还是远程例如 Github)?

3个回答

8
简单!假设submodule_dir是您希望将其作为子模块化的目录名称(假设它尚未受到git控制)。
cd submodule_dir
git init
git add .
git commit
# on github, create the new repo, then:
git remote add origin git@github.com:your_username/your_repo_name.git
git push -u origin master
cd ..
mv submodule_dir submodule_dir_delete_me
git submodule add git@github.com:your_username/your_repo_name.git submodule_dir

稍后(一旦您满意)
rm -rf submodule_dir_delete_me

当我想要将一个新文件夹作为新的子模块添加时,这对我非常有效。如果有人犯了像我一样的错误,并在git submodule add中输入了错误的submodule_dir路径,则可以通过git mv wrong_path correct_path命令进行修复,git会自动修复子模块管道并移动子模块。(此mv子模块需要> git版本1.8.5) - texdevelopers

6
我不明白你怎么能做到:子模块定义上是来自另一个仓库的SHA1(也就是说,父仓库必须存在才能提取该SHA1),你必须在父仓库中引用.gitmodules文件中的地址。

子模块由主仓库中所谓的gitlink tree entry组成,它指向内部仓库中的特定提交对象,该对象完全独立。

submodule.<name>.url

定义一个URL,用于克隆子模块存储库。它可以是一个绝对URL,可直接传递给git-clone(1),也可以是(如果以./../开头)相对于超级项目的源存储库的位置。

因此,您可以在本地创建子模块存储库,但无论如何都必须创建它。


5
git init .; mkdir a; cd a; git init .; cd..; git submodule add ./a a 这样做怎么样?是不是不好的主意? - manuels
@manuels,这就是我在我的答案中刚刚添加的内容,但关键是:您必须创建一个存储库才能将其作为子模块引用到父存储库中。然而,我不知道一旦您的父存储库被推送到GitHub并被另一个用户克隆后,它会如何运行。 - VonC
2
那么,如果我在超级仓库的目录中创建仓库,并将其用作子模块,这样做就可以了吗? - manuels
@manuels 是的:您可以声明一个子模块,它是主存储库的嵌套存储库。问题在于:任何克隆您的主存储库(您已经推送到GitHub)的人都无法访问您的嵌套存储库(即使也推送到GitHub),因为“./myNestedRepo”网址将引用他们本地工作站上的空目录。 - VonC
2
如果您太懒得登录到Github(或离线),并且想要立即创建子模块并稍后推送它,则可以使用此方法。 - Thibault D.

6

如果我理解正确,以下是我经常在Eclipse项目和工作空间中所做的事情。让我们从这个结构开始:

$ find .
.
./projekt.txt
./sub1
./sub1/sub1.txt
./sub2
./sub2/sub2.txt

首先初始化子模块和主模块:

$ cd sub1
$ git init
$ git add *
$ git commit -m "init sub1"
$ cd ../sub2
$ git init
$ git add *
$ git commit -m "init sub2"
$ cd ..
$ git init
$ git status
# On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   projekt.txt
#   sub1/
#   sub2/

要将这些文件夹作为子模块添加,而不是常规文件夹,请执行以下命令,并使用相对路径,例如./sub,而不是仅使用sub
$ git submodule add ./sub1
$ git submodule add ./sub2

现在它应该看起来像这样。
$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   .gitmodules
#   new file:   sub1
#   new file:   sub2
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   projekt.txt

最后在父文件夹上执行 git add *git commit -m "init parent",完成了!如果你现在更改了一个子模块中的文件,为了使别人在克隆你的父仓库时得到最新版本的子模块,你必须先提交子模块,再提交父仓库。

1
如果子模块在另一个文件夹中,比如 ./sub1/sub2,那么 git submodule add ./sub1/sub2 会将 sub2 克隆到 . 中,这不是你想要的。为了解决这个问题,请使用 git submodule add ./sub1/sub2 ./sub1/sub2。第一个路径指定从哪里添加,第二个路径指定添加到哪里。 - nwp
当我尝试提交.gitmodules和子模块文件时,出现错误:“无法添加到索引 - 缺少--add选项?” - Bakaburg
问题已解决,我需要先提交.gitmodules文件,然后再提交子文件夹。 - Bakaburg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接