Git: 将带有 repos 的目录变成带有子模块的 repo

Git: turn a directory with repos into a repo with submodules

我正在“软件”目录中开发我的项目。项目分为子目录:

software
  |
  +-- common_forms
  |     +-- .git
  +-- common_utils
  |     +-- .git
  +-- gui_app
  |     +-- .git
  + ...
  ... and so on.

每个子目录都是一个 git 仓库;主目录“软件”不是仓库,只是仓库的根目录。

现在我想将主目录“软件”变成一个存储库,并将这些存储库作为主存储库的子模块包含在内。我怎样才能做到不破坏目录和存储库的现有结构?

让我在这里添加一个词——有点多余,但对于强调很重要——

Each subdirectory is already a git repo; the master directory "software" is not a repo, just a root for the repos.

在这种情况下,只需进入 software 目录,运行 git init 创建一个 .git 目录/存储库,以此作为其顶级工作树,并且对每个不同的子模块使用 git submodule add。有关 git submodule add 的详细信息,请参阅 the git submodule documentation。然后 git add .gitmodules 文件并提交,以进行初始提交。

请注意,每个 git submodule add 命令的 repository 参数可以与 path 参数相同。这会影响 .gitmodules 文件中的内容,一旦您在刚刚创建的超级项目中进行提交,该文件现在可用于此超级项目的 未来 克隆。

也就是说,在未来,某人——让我们给他或她起个名字,例如帕特——将 运行:

git clone $URL [<path>]

从某些 URL 克隆子模块(现在我假设它在 $URL 中,尽管 Pat 可能会输入文字字符串而不是使用变量)。然后 Pat 会 cd 进入克隆和 运行,例如 git submodule update --init.

此处 Pat 的克隆需要 git submodule initgit submodule update --init 的说明。这些说明告诉 Git 所有子模块是什么以及如何 git clone 每个子模块。也就是说,现在 Pat 不必 运行 每个子模块一个 git clone,Pat 的 git submodule update --init 允许 Pat 的 Git 从 .gitmodules 文件中读取,每个 这些 git clone 操作所需的 URL 和路径名。

路径相对伪URL,例如./common_forms,变成URL-相对URL。也就是说,由于 Pat 克隆了 $URL 来创建超级项目,因此 .gitmodules URL ./common_forms 变成了 URL ${URL}/common_forms。如果这是对的URL,那一切都很好

另一方面,假设您计划将超级项目推送到 host1.example.com/supers/superproj.git,但所有 子模块 都将位于 URL,如 [=38] =].然后,当你创建 .gitmodules 文件时——或者至少在提交它之前——你应该确保将 存储在 中的 .gitmodules 文件是 host2.example.com/subs/common_formshost2.example.com/subs/common_forms.git。这样帕特仍然可以 运行 git submodule update --init.

(如果可能的话,安排存储库托管以镜像超级项目和子模块布局是最有意义的,但并非总是如此。)