使用Git复制子模块

时间:2010-11-06 23:55:33

标签: git git-submodules

我在Git中有一个包含多个子模块的项目,我需要下载这些子模块以及可用的文件才能使用主项目,为了让子模块工作,我需要自己的子模块才能使用所以为了设置它,我使用git submodule update --init --recursive递归初始化子模块。

但是,我注意到我的许多子模块都有共享依赖关系,在伪代码中看起来像这样(alpha -> beta表示alpha有子模块beta

my project -> submodule a -> submodule m
           -> submodule b -> submodule m
                          -> submodule n -> submodule x
           -> submodule c -> submodule x

我的问题是:有没有办法只使用git来避免这种重复,同时仍然拥有每个子模块的文件(至少有一份副本)?

我可以想象一个带符号链接的解决方案,但如果git为我处理这个问题会更好,而且我不确定在更新子模块时自己输入符号链接是否会引起问题。

理想情况下,我希望将其简化为:

my project -> submodule a -> symlink(submodule m)
           -> submodule b -> symlink(submodule m)
                          -> symlink(submodule n)
           -> submodule c -> symlink(submodule x)
           -> submodule m
           -> submodule n -> symlink(submodule x)
           -> submodule x

提前感谢任何建议!

2 个答案:

答案 0 :(得分:7)

这不是内置于git中,但你可以像你说的那样使用符号链接。你可能想看一下git new-workdir(来自git的contrib目录),基本上就是这个。它不知道与子模块有什么关系,但子模块不知道它是一个子模块 - 它是知道这些东西的父repo。我没有试过这个,但我相当肯定你可以使用这样的东西:

# remove the target first (new-workdir will refuse to overwrite)
rm -rf submodule_b/submodule_m

#               (original repo)         (symlinked repo)
git new-workdir submodule_a/submodule_m submodule_b/submodule_m

它通过符号链接基本上所有的.git目录来工作;没有符号链接的值得注意的是HEAD;这两个目录可以签出不同的东西,但共享相同的引用和对象。

从这里你应该很好。当您在超级模块中运行git submodule命令时,它只会进入子模块并在那里运行适当的命令,这些命令都将按预期工作。

你通常需要注意的一件事就是这样的符号链接repos就是它们共享同一组分支,所以如果它们都检出了相同的分支,并且你在一个分支中承诺它,那么另一个变得不同步。对于子模块,这通常不会成为问题,因为除非你介入,否则它们基本上总是处于分离的HEAD状态。

答案 1 :(得分:3)

git-new-workdir可能不是这里讨论的好解决方案: http://comments.gmane.org/gmane.comp.version-control.git/196019

根据git 1.7.10,它对我不起作用。

我已经使用硬链接为我的用例解决了这个问题。我正在运行OS X,文件系统允许创建到目录的硬链接: https://github.com/darwin/hlink

现在我可以硬链接子模块目录,git透明地处理它们。硬连接也有很好的属性,所有子模块都是完全镜像的,包括HEAD,这是我喜欢的行为。

好的,想法是拥有一个“主”子模块repo并将所有“slave”副本硬链接回它。这将使他们彼此无法区分并完全同步。

<强> CAVEATS

1)只要.git中的相对路径有效,这就可以正常工作。换句话说,您只能硬链接位于目录树中相同目录级别的子模块。这是我的情况。我假设您可以通过使用硬链接任务修改.gitfiles来轻松修复它。注意:这在git 1.7.10之前应该没有问题,因为以前的子模块的.git是一个自包含的目录,而不仅仅是明文.git文件指向其他地方。

2)硬链接可能会引入一些不兼容性。例如,TimeMachine变得混乱,因为它在内部使用硬链接进行版本控制。确保从TimeMachine中排除项目目录。

以下是我执行此工作的佣金任务示例: https://github.com/binaryage/site/blob/3ef664693cafc972d05c57a64c41e89b1c947bfc/rakefile#L94-115