假设我有3个git存储库,每个存储库的根目录中都有一个lib和tests文件夹.所有3个存储库都是我想成为一个软件包的一部分,但是对我来说,将存储库分开是很重要的.
我是svn的git新手,所以我一直在阅读子模块以及它们与svn:externals的区别.在SVN中,我可以有一个
lib/vendor/package
目录和内部包中,我可以设置3个外部对象,这些外部对象指向我的3个存储库lib目录中的每一个,并将其重命名为
lib/vendor/package/a -> repo1/lib
lib/vendor/package/b -> repo2/lib
lib/vendor/package/c -> repo3/lib
但是据我了解,使用git无法做到这一点.我想念什么吗?
真的,我希望可以通过以下两种方法之一解决此问题.
>有人会指出如何创建第4个git存储库,该存储库将其他3个子模块组织为如上所述(在根目录中可以有a,b和c文件夹)
>有人会指出如何使用svn:externals结合github的svn支持进行设置,并引用每个git存储库中的lib目录(据我所知这是不可能的)
更新:
我实际上已经尝试遵循您链接到的子模块教程,但是遇到了以下问题.
如上所示执行操作,而不是像
lib/vendor/package/a -> repo1/lib
lib/vendor/package/b -> repo2/lib
lib/vendor/package/c -> repo3/lib
我留下了
lib/vendor/package/a -> repo1
lib/vendor/package/b -> repo2
lib/vendor/package/c -> repo3
这是不理想的,因为现在要访问repo1的lib文件夹中的ClassA,路径为
lib/vendor/package/a/lib/ClassA
当我真正想要得到时(这可以通过svn:externals实现)
lib/vendor/package/a/ClassA
因为上面的实际上是repo1 / lib,而不是repo1的根目录.
这样的事情很重要,因为例如在PHP5.3中,使用SplClassLoader(http://gist.github.com/221634)时,它需要一个名称空间到目录的映射,例如
\Package\a\ClassA -> lib/vendor/package/a/ClassA
这是我概念上的误解所在,如何设置第4个git存储库以允许如上所述的目录映射.
解决方法:
没错,Git子模块不能直接做您想要的事情.它在SVN中工作,因为存储库的根,分支及其任何子目录是同一类型的对象.在Git中,存储库,分支和目录都是不同的对象(您不能将目录用作完整的存储库或分支).
虽然有两种间接的方法可以实现您想要的.
使用子模块和符号链接
Git子模块的核心是“超级项目” *工作树中另一个存储库的克隆.
Git仅克隆完整的存储库.不可能仅从现有存储库中克隆一个子目录†.
*常规子模块还需要在超级项目的commits / index中有一个特殊的引用,并且(通常)在超级项目的.gitmodules文件中需要一个条目.
可以在不相关的工作树中具有其他存储库的非跟踪克隆,但是这种用法不会创建子模块.
†Git 1.7.0及更高版本具有“稀疏签出”功能,但它无助于将lib目录重新定位到每个子模块克隆的顶层.
但是,您可能可以使用Git对符号链接的支持来完成相当接近的操作:
#
# Make the lib directory of each submodule appear in the superproject as
# lib/vendor/packages/$submod_name
#
# With this structure in each of the submodules (a, b, c):
#
# lib/
# tests/
#
# We end up with this structure in the superproject:
#
# lib/
# vendor/
# packages/
# a (a symlink to ../../../_submodules/a/lib)
# b (a symlink to ../../../_submodules/b/lib)
# c (a symlink to ../../../_submodules/c/lib)
# _submodules
# a/ (a Git submodule)
# lib/
# tests/
# b/ (a Git submodule)
# lib/
# tests/
# c/ (a Git submodule)
# lib/
# tests/
#
add_one() {
dir=lib/vendor/package
dest="$dir/$1"
# use fewer ".."s to put the _submodules closer to the symlinks
s=../../../_submodules/"$1"
git submodule add "$2" "$dir/$s"
ln -s "$s"/lib "$dest"
git add "$dest"
}
cd "$main_repo_toplevel"
mkdir -p lib/vendor/package
add_one a git@githost.example.com:user/package-a.git
add_one b git://public.example.com/work/package-b-dev.git
add_one c ssh://special.example.com/foo.git
使用git子树
apenwarr的git subtree可以拆分并合并部分存储库(即单个子目录;它是“subtree merging”的包装器以及其他不错的功能).第一步将是提取每个子项目中lib的历史记录.然后,直接将提取的历史记录用作子模块,或使用git subtree将子树合并到您的主存储库中.无论哪种方式,这都将引入一个额外的步骤(重新提取lib历史记录),然后才能将子项目中的更改集成到主存储库中.
标签:svn,git,php
来源: https://codeday.me/bug/20191210/2098804.html