具有单个子模块的多个回购

Roc*_*ist 8 git git-submodules

我找了一会儿却找不到答案(也许我不知道该看什么).

我们有一个主库,它是一个自己的存储库(让我们称它为Lib)它包含我们的大多数模块和子模块.我们还说它的大小为2GB ......

现在我们有很多项目,例如:ProjA,ProjB,ProjC,每个项目都使用Lib作为子模块.

ProjA

  • Lib(分支:master,commit#:1)

ProjB

  • Lib(分支:其他,提交#:2)

ProjA

  • Lib(分支:master,commit#:4)

因此,虽然我能够保持每个项目引用正确的库(aka子模块)版本.我现在有3*2GB = 6GB的THE SAME子模块.

有没有办法在保持引用的正确文件/版本控制的同时引用单个子模块?

例如.

ProjA

  • Lib/base_lib.h(v1.0)

  • LIB/file_only_in_this_commit

ProjB

  • Lib/base_lib.h(v1.0)

ProjC

  • Lib/base_lib.h(v1.1)

谢谢!

yai*_*chu 7

您可以使用git worktree(自git 2.5起可用)为Lib子模块创建额外的工作树,位于ProjA,ProjB等内部.

因为git worktree使多个具有相同名称的工作树(所有被称为"Lib")变得很痛苦,我只是创建了一个脚本,share_submodules来解决这些困难并创建额外的工作树而不是子模块,将其设置为正确的子模块提交,并以递归方式对共享模块中的所有子模块执行此操作.

git submodule update --init --recursive除了所有副本都引用一个模块的对象之外,它应该像子模块一样工作.

如果您通过删除子模块转换到它,那么您.git和我创建的stray子模块文件会创建find_stray_submodules.py来清理它们.


use*_*253 3

嗯,整个子模块的内部结构非常简单,因此您可以根据自己的喜好掌握它。

在每个文件中Proj<N>/.git/modules/都有一个与子模块相对应的文件夹,其中包含从/.gitmodules 中Lib指定的远程引用克隆的裸存储库。这些裸存储库是优化点。Proj<N>Lib.url

您可以在可能的情况下使用硬链接简单地重新创建它们。

Lib1)在与所有 Proj 存储库相同的文件系统上的文件夹中创建您的裸克隆:

 git clone --bare url://to/Lib /path/to/Lib.git
Run Code Online (Sandbox Code Playgroud)

2) 将默认子模块存储库替换为存储库,引用 p.1 中的裸存储库:

mv ProjA/.git/modules/Lib ProjA/.git/modules/Lib.old // preserve it for a while
git clone --bare --local url://to/Lib \
    --reference /path/to/Lib.git ProjA/.git/modules/Lib
Run Code Online (Sandbox Code Playgroud)

3) 从保存的存储库中恢复配置ProjA/.git/modules/Lib

cp ProjA/.git/modules/Lib.old/config ProjA/.git/modules/Lib/config
Run Code Online (Sandbox Code Playgroud)

现在您可以检查一切是否正常ProjA并删除ProjA/.git/modules/Lib.old等等。在这种情况下,所有存储库将使用相同的文件对象。

在 git 中,子模块的特定状态由精确的 SHA1 引用。除非您在Lib主存储库中执行一些“邪恶”操作(例如git filter-branch或可能导致删除提交的其他操作),否则所有正确的提交Lib都会永远保留。您Proj<N>签出的特定提交完全独立于彼此,因此您不必担心Libin的状态ProjA可能会干扰Libin的另一个状态ProjB