首页 > 解决方案 > 是否可以将子模块更改保存到主 git 索引?

问题描述

直到最近,我一直通过复制/粘贴来管理模块,但后来我发现了子模块,并且通过单分支克隆,使用此功能变得更加明智。

但是我有几个问题,希望有人可以帮助我。

  1. 是否可以在主 git 索引中保存模块更改而不是它自己的模块?

我的意思是我试图在 github 上拥有一个具有基本/基本设置的中央模块,并且在每个拉取/需要这个模块的项目下,该项目可以进行与他单独相关的更改并将这些更改保存到他的 git 索引中,所以我们可以稍后克隆项目,所有的变化都会在那里。

如果这是不可能的,那么可行的选择是什么?


# 部分解决方案

使用git diff --submodule=diff > modules_changes.diff& 以后只需使用git apply modules_changes.diff

但是,这不适用于已更改的文件“删除/添加的文件”

# 更好的解决方案

为每个模块设置一个 repo 并为每个项目设置分支


  1. 如何在添加时自动设置模块头?

atm 当您在处理项目时想要将某些内容推送到模块时。这些步骤通常是

但是我想知道是否有一种方法可以自动执行此操作,因此诸如自动推送提交之类的操作将直接起作用,而无需在每个模块更改时手动执行上述步骤。

标签: gitgit-submodules

解决方案


简短的回答是否定的:超级项目提交所做的唯一事情是通过哈希 ID引用某些子模块提交。

请记住,在使用子模块时,您实际上只是在使用两个几乎完全独立的 Git 存储库。我说几乎是因为超级项目是指子模块。

在超级项目中,.gitmodules文件中有一些说明。这些说明说明了超级项目应该如何运行git clone。特别是git clone需要一个 URL,并且在提交中没有存储 URL 的地方:

  • 提交具有元数据,包括tree一行。该tree行指的是一些内部树对象的哈希 ID。
  • 内部树对象由“行”组成(但采用二进制格式;请参阅git mktreegit ls-tree了解非二进制文本格式)。这些行中的每一行代表一个记录。每条记录都包含:
    • 一种模式,例如,100644用于常规的非可执行文件;
    • 哈希 ID,例如c592dda681fecfaa6bf64fb3f539eafaf4123ed8;和
    • 路径名组件,例如.clang-format.
  • 符号链接的模式是120000,符号链接的内容存储为 blob 对象。
  • gitlink (对子模块的引用)的模式是160000,树条目中的哈希 ID是子模块的提交哈希 ID 。

所以只有哈希 ID 的空间,而不是 URL。因此 URL 存储在超级项目中的其他位置(.gitmodules和/或您的.git/config)。

子模块的名称源自路径,而路径又源自tree用于到达“gitlink”条目的对象:带有 mode 的事物160000。该路径对应于超级项目中的某个目录。在该目录中,应该有一个 Git 存储库。如果没有,git submodule init可以使用 URL(在任何地方找到)运行git clone以使用 Git 存储库填充该目录。

一旦存储库就位,超级项目就可以运行:

(cd $path && git checkout $hash)

该路径在哪里$path,并且$hash是 gitlink 中的哈希值。该哈希 ID 最好存在于克隆中!如果不是,则超级项目检出失败(Git 让您自己清理)。

因此,超级项目 Git 存储库实际上只能在子模块 Git 存储库执行 rungit checkout或其他一些 Git 命令。如果有办法git apply在各种补丁文件上运行,那可以做你想做的事,但这不是 Git 内置的。

(请注意,有些系统会做这种事情。甚至使用 Git:see guilt,它是基于 quilt 构建的,它的名字来源于将许多补丁串在一起的想法。)


推荐阅读