【问题标题】:Git repository in a Git repositoryGit 存储库中的 Git 存储库
【发布时间】:2011-05-12 16:05:39
【问题描述】:

我有一个 Git 存储库,包括一个 Git 存储库。

repo1/
     .git/
     files
     repo2/
          .git/
          files
     files

是否可以使用这种架构?

【问题讨论】:

  • 我应该认真考虑使用子模块。
  • 您为什么要考虑这样做?可能还有其他选择。
  • 当您使用作为单独存储库托管的框架和框架组件时,自然会出现此“问题”。例如,如果你签出一个 WordPress 或 Vagrant+WordPress 项目,然后你签出一个 WordPress 主题,也许还有一些位于第一个 repo 的文件结构中的插件。它们中的每一个通常都是它们自己的 git 存储库,而不是子模块。我只是将这些第 3 部分存储库中的每一个的根文件夹添加到其父存储库的 gitignore 文件中。

标签: git


【解决方案1】:

你可以有嵌套的 git repos:
父 repo 将简单地忽略嵌套 repo

jleedev cmets 并用 gist script 说明父 repo 将通过 a gitlink 跟踪嵌套的 repo 状态。
(gitlink = 对象的 SHA-1 引用另一个存储库中的提交。Git 链接只能由 SHA 或通过提交标记指定。
gitlink 有一个特殊的模式 '160000',用于子模块,但也用于简单的嵌套 repos)。

但是,通常的命令不会承认嵌套的 repo:addcommit 仅适用于一个 repo,而不适用于另一个 repo。

git submodule 将允许从父 repo 引用嵌套 repo,并保留对子 repo 的精确引用。

另一种选择可能涉及:

  • 两个独立的 Git 存储库(未嵌套)
  • 从一个到另一个特定部分的符号链接(Unix 和 Windows Vista+ 都有符号链接)

【讨论】:

  • 父仓库不会忽略它;它将使用 gitlink 跟踪 HEAD。
  • 不幸的是稀疏;大多数文档都在谈论子模块而不是 gitlinks。在Documentation/ 中搜索160000gitlink。这是an example gitlinks 的行为方式。
  • 最值得注意的是,gitlink 是树/索引条目,而子模块是可以克隆和同步您的 gitlinks 的 UI。文档并没有真正解释这一点。
  • @jleedev:非常好。我已将您的评论整合到我的回答中,将链接添加到 git fast-import 手册页,这是 Git 中唯一明确提到 gitlink 是什么的文档。
  • 如果您执行git add .git add inner-repo,则结果是一个 git 链接,如此处所述。但是,如果您执行git add inner-repo/(斜杠),那么它会将文件添加到存储库中,并开始像跟踪任何其他文件一样跟踪它们(inner-repo/.git 除外,它会忽略它)。所以结果是两个repos分别跟踪文件,互不了解。
【解决方案2】:

您正在尝试完成称为“子模块”的事情。

请查看 Git Tools - Submodules 了解它的工作原理。

【讨论】:

  • 是的,我在说,更多关于明天的实验:3
【解决方案3】:

我已经使用该结构很长一段时间了,在外部 repo 的 .gitignore 中指定了子 repo 目录。

它混淆了我的编辑器 (PhpStorm) 中的 git 工具,它总是想要提交到外部 repo,但在其他方面工作正常。我将整个外部存储库(包括所有内部存储库)作为单个项目加载到编辑器中。这让我可以在处理内部代码时轻松搜索和检查外部代码库中的代码。

我在我正在处理的任何 repo 中从 Git bash 执行所有 Git 操作。

子模块可能是更好的方法。我还没有时间调查他们是否会更好地与 PhpStorm 一起工作。

【讨论】:

    【解决方案4】:

    是的,您可以使用此模式。我过去用它来将 SVN 外部引入 git-svn 克隆。子模块现在可能会更好地处理这个问题,但当时并不适合我的需求。

    您需要将以下内容添加到 repo1/.git/info/exclude 以确保 repo2 中的更改不会与 repo1 混合:

    repo2
    

    【讨论】:

      【解决方案5】:

      我也同意Ronald William's answer。 Git 子模块的主要目的是更新从外部世界获取的代码,如果该代码被更新修改,则无需提交更改。

      Composer 包管理系统也是如此。实际上 they don't recommend to commit those changes either 并忽略项目根目录中 .gitignore 中的 vendor 文件夹。

      如果您尝试提交此文件夹,那将是一场噩梦,因为某些 vendor/some_repo 可能是开发版本,因此它们有一个 .git 文件夹,这会导致所有这些即使您不使用 git submodule add 添加软件包,它们也会成为子模块。如果您在嵌套的 .git 存储库中修改 some_file,您可能会看到类似的内容:

      ~/project_root $ git status
      # On branch master
      # Changes not staged for commit:
      #   (use "git add <file>..." to update what will be committed)
      #   (use "git checkout -- <file>..." to discard changes in working directory)
      #   (commit or discard the untracked or modified content in submodules)
      #
      #    modified:   vendor/nested_repo (modified content)
      

      请注意 modified content in submodules 条目,并且您在输出中看不到 some_file 名称。相反,您会看到 (modified content) 通知,因为 root_project .git 将 vendor/nested_repo 视为子模块,并且不会跟踪该文件夹中的单个文件。

      如果您运行 git add --all,则在您在 vendor/nested_repo 中提交更改之前,您将不会得到任何结果,只有在此之后,您才能在根存储库中提交更改。

      不要这样做。相反,如果您想将项目保留为一个完整的 .git 存储库(任何,不仅是 Composer 构建的存储库),这有时非常方便,请将此条目添加到根 .gitignore BEFORE 初始提交:

      .git
      !/.git
      

      不幸的是,要使整个配方起作用,您需要为以后要单独修改的每个嵌套存储库运行git add 命令。请注意,存储库路径中的尾部斜杠是必须

      ~/project_root $ git add vendor/some_repo/ vendor/another_repo/
      

      然后修改vendor/some_repo中的some_file,看看有什么区别:

      ~/project_root $ git status
      # On branch master
      # Changes not staged for commit:
      #   (use "git add <file>..." to update what will be committed)
      #   (use "git checkout -- <file>..." to discard changes in working directory)
      #
      #    modified:   vendor/some_repo/some_file
      

      这样您就可以像往常一样在project_root 中运行git add --all 然后git commit "Changes ..."

      【讨论】:

        【解决方案6】:

        还有包管理解决方案。

        Git 子模块确实允许您使用您描述的架构进行开发,并且 Git 子树提供了许多人喜欢的类似解决方案。

        在我看来,包管理软件是任何复杂项目不可或缺的一部分。我喜欢Composer,因为它支持直观的工作流程。

        很遗憾,PhpStorm 不支持 Git 子模块:

        Git submodules should be supported (IDEA-64024)

        【讨论】:

          猜你喜欢
          • 2011-05-28
          • 1970-01-01
          • 2013-02-23
          • 1970-01-01
          • 1970-01-01
          • 2016-08-15
          • 2018-04-05
          • 2013-12-10
          • 2014-04-08
          相关资源
          最近更新 更多