如何将一个git仓库添加为另一个git仓库的共享依赖?

8
我需要类似于子模块的东西,但是它作为依赖存在于主存储库之外。 问题如下: 我正在尝试使用Git(以一种非常笨拙的方式)来管理CAD工具(Cadsoft Eagle)的设计文件,但我很难弄清楚是否有一种方法可以使用git子模块来管理每个项目对CAD工具共享库的依赖关系。
我使用的文件夹结构如下:
~/eagle/ <-- Main library used by multiple projects
    .git/     
    <library files>

~/projects/ <-- Projects folder
    Proj0/
        .git/
        <design files>
    Proj1/
        .git/
         <design files>

在这种情况下,为每个项目添加eagle.git存储库作为git子模块是没有意义的。
然而,我仍然需要一种方法来快照当前状态的“eagle.git”存储库,以便在将来更新库时,可以回滚到访问Proj[x]提交时使用的特定版本的库文件。
理想情况下,我希望有以下功能:
~/eagle/ <-- Main library used by multiple projects
    .git/     
    <library files>

~/projects/ <-- Projects folder
    Proj0/
        .git/
        <design files>
        **eagle** <-- something that acts like a submodule  
                      but which actually points to ~/eagle/
    Proj1/
        .git/
         <design files>
         **eagle** <-- something that acts like a submodule  
                       but which actually points to ~/eagle/

我希望能够:

cd ~/projects/Proj0
git submodule update

我希望当Proj0的版本被检入时,~/eagle/目录能够自动回滚。

有没有人知道Git中是否有任何东西可以实现这种行为?


你能解释一下为什么子模块在这里行不通吗?在我看来,子模块恰好是你所需要的。 - Dan Moulding
对于 CAD 工具(Eagle)来“看到”库,必须将其添加到 Eagle 的路径设置中。如果我为每个项目添加“eagle”库存储库作为子模块,那么我必须手动将每个项目的子模块库路径附加到 Eagle 的路径设置中,这将导致 [x] 份“eagle”库副本出现在 Eagle 的库管理器中。在 CAD 工具中找出哪个是哪个,并管理这些单独的副本将是一场噩梦。此外,该库的大小可能比项目文件大几个数量级,因此在磁盘上保留 [x] 份副本似乎非常浪费。 - cdwilson
一个有帮助的思考方式是通过类比。假设Eagle CAD工具是一家每次只能制造一个小部件的工厂。假设每个project[x].git仓库都代表了某个小部件[x]的制造蓝图[x],而eagle.git仓库则代表了制造该小部件[x]所需的工厂设置(机器、工人、原材料)。 - cdwilson
我需要的是一种方法,将蓝图[x]与制造该小部件[x]所需的当前工厂状态进行标记。这样,如果制造小部件[x]的工厂设置更改为制造小部件[y],工厂所有者可以稍后使用来自蓝图[x]的标记将工厂恢复到制造小部件[x]所需的确切设置。 - cdwilson
必须为每个蓝图保留一个单独的工厂并不太合理,但是拥有一个可以重新配置以制造所有[x]个小部件的单一工厂是必要的。在这种情况下,子模块并不真正合理,因为eagle.git 库在概念上不是每个项目的组件(或任何子组件),就像工厂不是小部件的子组件一样。 - cdwilson
然而,eagle.git 存储库的当前状态(即修订版)对于 CAD 工具精确地重新创建项目.git 存储库中特定输出是必需的,这就是为什么我需要将其检入项目.git 存储库的原因。(类似于不同的 Makefile 可以从相同的源代码创建不同的二进制文件的方式) - cdwilson
2个回答

5
对于每个项目,请添加.git/hooks/pre-commit文件(并确保它是可执行的):
#!/bin/sh
git --git-dir=~/eagle/.git log -1 --pretty=format:%H >.eagle_rev
git add .eagle_rev

然后,对于每个项目:
git config alias.update-eagle '!git --git-dir=~/eagle/.git --work-tree=~/eagle checkout -q $(<.eagle_rev)'

当您进行提交时,它将记录~/eagle的当前HEAD,并且git update-eagle将在~/eagle中检出该提交。(然后只需确保在对其进行任何更改之前,在~/eagle中执行git checkout <branch>。)

mkarasek,你是新的热点!我之前对钩子一无所知...但是,由于某种原因,在--git-dir路径中使用“”会返回错误“fatal: Not a git repository: '/eagle/.git'”。然而,如果我用“$HOME”代替“”(即'--git-dir=$HOME/eagle/.git'),它就可以正常工作。你有什么想法为什么“”不能与--git-dir和--work-tree一起使用吗? - cdwilson
你在使用提交钩子时遇到了那个错误吗?可能是因为你的/bin/sh与之有问题;将第一行替换为#!/bin/bash,看看问题是否解决。(另一方面,如果你在使用别名时出现了那个错误,我就不清楚了。) - mkarasek

0

如果eagle没有在ProjX中占据一席之地,
但是每个ProjX可以使用特定版本的eagle
那么:

对于每个ProjX,您需要:

  • 拥有一个MainProjX Git repo,其中您会找到:
    • 一个ProjX
    • eagle的版本(与ProjX处于相同级别

每个MainProjX父项目的目标是将ProjXeagle的版本保持在一起,也就是记录正确的依赖关系。

~/projects/ <-- Projects folder
    MainProj0
      Proj0/
          .git/
          <design files>
      eagle/
          .git/
          <library files>

    MainProj1
      Proj1/
          .git/
          <design files>
      eagle/
          .git/
          <library files>

现在,是的,那是很多'eagle'重复,但如果每个ProjX能够使用自己的eagle修订版,这是必要的。


VonC,感谢您的快速回复。 是的,那也是我能想到的唯一方法了... 问题在于“eagle”仓库可能非常庞大(整个CAD库),而Proj[x]仓库非常小。就像你说的那样,我必须保留大量“eagle”仓库的副本,甚至更糟的是,我必须手动更改CAD工具的库路径以便工具能够看到它们,这使得这种方法几乎无法使用。 - cdwilson
1
@lotharsmash:每个库的相对路径“../eagle”不是已经足够了吗?(因为eagleProjX在同一层级) - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接