有没有一种方法可以添加没有嵌套子模块的git子模块?

有没有一种方法可以添加没有嵌套子模块的git子模块?,git,git-submodules,Git,Git Submodules,我有三个存储库 复印机 报告 安息 repocomon作为子模块添加到RepoTn和RepoTh。RepoTn和RepoTh都是两个不同的存储库,因为在开发早期,人们认识到这两个存储库是独立的应用程序。但是现在在开发部分的后面,我们意识到RepoTn高度依赖于RepoTh 作为解决方案,我正在考虑将repath作为子模块添加到RepoTn。但有一件事困扰着我,那就是reposomon内部的reposh。如果我这样做,它将基本上具有以下结构: 报告 复印机 安息 repocomon->这

我有三个存储库

  • 复印机
  • 报告
  • 安息
repocomon
作为子模块添加到
RepoTn
RepoTh
RepoTn
RepoTh
都是两个不同的存储库,因为在开发早期,人们认识到这两个存储库是独立的应用程序。但是现在在开发部分的后面,我们意识到
RepoTn
高度依赖于
RepoTh

作为解决方案,我正在考虑将
repath
作为子模块添加到
RepoTn
。但有一件事困扰着我,那就是
reposomon
内部的
reposh
。如果我这样做,它将基本上具有以下结构:

  • 报告
    • 复印机
    • 安息
      • repocomon->这是我试图删除的部分
我想知道当我想将它作为子模块添加到
RepoTn
时,是否可以从
RepoTh
中删除
repocomon


注意:
resoth
需要继续存在,因为它也是自己独立的存储库。另外,我问这个问题的另一个原因是,如果我可以删除/忽略
repocomon
,我可以修改项目文件,以确保系统使用正确的
repocomon
文件夹。我正在使用Visual Studio 2019,如果这有什么不同的话。我们也欢迎您提出任何其他更好的解决方案建议。

如果可能,您应该添加一个额外的存储库,该存储库将记录这些依赖项:

RepoTnParent
  RepoTn
  RepoTh
  RepoCommon

这样,如果您需要构建
RepoTn
,您将加载
repotnpresent
,这将依次加载正确的版本
RepoTn
RepoTh
repocomon
,简短的答案是否定的。这会产生一个问题,您可以使用长答案来解决,但避免这种设置可能是明智的。看

长话短说 您必须记住这里的子模块是什么,但在我们开始之前,让我们确切地定义Git存储库是什么。对此有很多小警告,但简言之,Git存储库是一个提交集合。1每个提交都有一个唯一的编号:一个大而难看的哈希ID,保留给该提交,跨越所有Git。该提交用于保存Git在提交时知道的每个文件的快照。2

除了这些存储的文件(内部保存为Git调用的blob对象)之外,Git还可以保存Git内部调用的gitlink。稍后,当我们谈到子模块时,我们将了解gitlink的确切形式

一旦您通过hash ID选择了一些提交,您可以让Git在存储库中通过分支名称进行查找,您就可以让Git签出该提交(使用
Git checkout
,或者,自Git 2.23以来,
Git开关
)。这将提取提交到一系列可用(且可修改!)普通文件中的文件。Git将这些文件复制到Git的索引中,该索引是Git用于进行新提交的每个存储库的数据结构。4如果提交包含任何gitlinks,Git还会将这些gitlinks复制到其索引中


1最大的警告是,存储库所在的
.git
目录实际上是两个主要数据库以及一些辅助数据。一种是从散列ID映射到内部Git对象,其中包括提交,但也包括其他三种对象类型。第二个映射名称,包括分支和标记名称,这是人类在这里主要用来散列ID的名称,例如,第一个数据库中的散列ID可以被人类使用

克隆存储库时,Git会按原样复制对象数据库,并使用另一个Git的名称对ID数据库进行哈希运算,以构建自己的(不同的)名称对ID数据库进行哈希运算。除此之外,不会复制任何辅助数据,如挂钩、索引或特殊伪引用(如CHERRY\u PICK\u HEAD-ref)。因此,对象数据库非常重要,因为人们使用名称数据库来定义他们的分支概念,而这与Git的概念并不完全相同,第二个数据库也很重要。然而,在这里,我们主要关注对象数据库

2除了快照,提交存储元数据,但这里我们只关心快照本身

3存储的文件以一种特殊的只读Git格式保存,在这种格式中,文件被压缩和(重要的)重复数据消除。进入索引的实际上是blob散列ID,因此索引“copy”根本不是真正的副本;但是索引还保存了文件名和使Git快速运行的数据

4索引具有其他角色,但通过保存每个文件的“副本”以及文件的路径名,索引将充当下一次提交的模板。当您使用
git add
时,您实际做的是更新git的索引,以便下一次提交不会与当前提交相同


gitlinks如何成为子模块 Git中的子模块只是另一个独立的Git存储库,具有一种特殊的关系:子模块Git存储库由其他Git存储库控制。控制Git存储库是超级项目,控制Git存储库是子模块

假设存储库的工作方式是签出提交,这样您就有了可以使用的文件,而不是只有Git自己才能使用superproject Git自己所需的特殊压缩格式的文件,一旦子模块Git存储库克隆到位,是在该子模块中运行
git checkout
。这就是它的作用:

cd $path
git checkout $hash
要想
git checkout
submodule中的一些提交,超级项目需要知道两件事:

  • 那条路是什么?上面的
    $path
    中有什么值
  • 散列ID是什么?有什么价值