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

时间:2015-12-08 09:06:37

标签: git git-submodules

我已经找了一段时间但没有找到答案(也许我不知道该看什么)。

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

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

  

ProjA

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

ProjB

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

ProjA

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

因此,虽然我能够保持每个项目引用正确的库(也称为子模块)版本。我现在有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)
  •   

谢谢!

2 个答案:

答案 0 :(得分:6)

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

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

如果子模块是由git submodule update --init --recursive创建的,它应该工作,除了所有副本都引用一个模块的对象。

如果您通过移除子模块转换到它,则.git中会有杂散的子模块文件,我创建了find_stray_submodules.py来清理它们。

答案 1 :(得分:3)

嗯,内部整个子模块很简单,所以你可以根据自己的喜好掌握它。

Proj<N>/.git/modules/对应Lib子模块的Proj<N> sa文件夹中,从Lib.url /。gitmodules Lib中指定的远程引用克隆裸存储库。那些裸存储库是优化的重点。

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

1)在与所有Proj存储库相同的文件系统上的文件夹中创建 git clone --bare url://to/Lib /path/to/Lib.git 的裸克隆:

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

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

ProjA/.git/modules/Lib

3)从cp ProjA/.git/modules/Lib.old/config ProjA/.git/modules/Lib/config 中保留的仓库恢复配置:

ProjA

现在,您可以检查ProjA/.git/modules/Lib.old中是否所有内容都有效并删除Lib,依此类推。在这种情况下,所有repos都将使用相同的文件对象。

在git中,子模块的特定状态由精确的SHA1引用。除非你表演一些邪恶的&#34;您git filter-branch主要仓库(例如Lib或其他可能导致删除提交的操作)中的操作,Proj<N>中的所有正确提交都将永久保留。您的Lib签出特定提交完全相互独立,因此您不应该担心ProjA中的Lib状态可能会干扰ProjB的其他状态在$file_name_with_full_path = realpath('./sample.jpeg'); $post = array('extra_info' => '123456','file_contents'=>'@'.$file_name_with_full_path); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$target_url); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); $result=curl_exec ($ch); curl_close ($ch);