git 子模块 svn 外部 [英] git submodule svn external

查看:35
本文介绍了git 子模块 svn 外部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有 3 个 git 存储库,每个存储库在根目录中都有一个 libtests 文件夹.所有 3 个存储库都是我希望成为单个包的一部分,但是将存储库分开对我来说很重要.

Let's say I have 3 git repositories, each with a lib and tests folder in the root. All 3 repositories are part of what I want to be a single package, however it is important to me to keep the repositories separate.

我是来自 svn 的 git 新手,所以我一直在阅读 submodules 以及它们与 svn:externals 的区别.在 SVN 中,我可以有一个

I am new to git coming from svn, so I have been reading up on submodules and how they differ from svn:externals. In SVN I could have a single

lib/vendor/package

目录,在 package 内部,我可以设置 3 个外部文件,指向我的 3 个存储库中的每一个 lib 目录,将其适当重命名为

directory, and inside package I could setup 3 externals pointing to each of my 3 repositories lib directory, renaming it appropriately like

lib/vendor/package/a  -> repo1/lib
lib/vendor/package/b  -> repo2/lib
lib/vendor/package/c  -> repo3/lib

但据我所知,这在 git 中是不可能的.我错过了什么吗?

but from my understanding this is not possible with git. Am I missing something?

我真的希望这可以通过两种方式之一解决.

Really I'm hoping this can be solved in one of two ways.

  1. 有人会指出如何创建第 4 个 git 存储库,该存储库将其他 3 个作为子模块组织起来,如我上面提到的(我可以在其中拥有 ab, 和 c 文件夹内的根目录)
  2. 有人会指出如何使用 svn:externals 结合 githubs svn 支持进行设置,引用每个 git 存储库中的 lib 目录(根据我的理解不可能)
  1. Someone will point out how to create a 4th git repository which has the other 3 as submodules organized as I have mentioned above (where I can have an a, b, and c folder inside the root)
  2. Someone will point out how to set this up using svn:externals in combination with githubs svn support, referencing the lib directory within each git repository (from my understanding this is impossible)

更新:

我实际上曾尝试按照您链接的子模块教程进行操作,但遇到了以下问题.

Update:

I had actually tried to follow the submodules tutorial you linked to, but I run into the following problem.

做如上图所示的事情,而不是像这样的映射

Doing things as shown above, instead of a mapping like

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

这并不理想,因为现在访问repo1lib文件夹中的ClassA,路径是

this is not ideal since now to access ClassA inside repo1's lib folder, the path is

lib/vendor/package/a/lib/ClassA

当我真的想得到(这可以通过 svn:externals 实现)

when I'm really trying to get (and this is possible with svn:externals)

lib/vendor/package/a/ClassA

因为上面的a实际上是repo1/lib,而不是repo1的根目录.

since a above is actually repo1/lib, and not the root directory of repo1.

这样的事情很重要,因为以 PHP5.3 为例,使用 SplClassLoader ( http://gist.github.com/221634 ),它需要一个命名空间到目录的映射,如

Something like this is important since, with PHP5.3 for example, using the SplClassLoader ( http://gist.github.com/221634 ), it requires a namespace-to-directory mapping like

PackageaClassA  -> lib/vendor/package/a/ClassA

这是我概念性误解的地方,如何设置第 4 个 git 存储库以允许我的目录映射如上.

this is where my conceptual misunderstanding is, how to setup that 4th git repository to allow my directory mappings like above.

推荐答案

你说得对,Git 子模块不能直接做你想做的事.它在 SVN 中工作,因为存储库的根、分支及其任何子目录都是同一种对象.在 Git 中,存储库、分支和目录都是不同类型的对象(您不能将目录用作完整存储库或分支).

You are right, Git submodules can not directly do exactly what you want. It works in SVN because the root of a repository, branches, and any subdirectory thereof are the same kind of object. In Git, a repository, a branch, and a directory are all distinct kinds of objects (you can not use a directory as a full repository or as a branch).

不过,有几种间接方法可以实现您的愿望.

There are a couple of indirect ways to accomplish what you want though.

Git 子模块的核心是超级项目"的工作树中另一个存储库的克隆*.Git 只克隆完整的存储库.不可能从现有存储库中只克隆一个子目录.

The core of a Git submodule is a clone of another repository in the work tree of the "superproject"*. Git only clones full repositories. It is not possible to clone just a single subdirectory out of an existing repository.

* 普通子模块还需要在超级项目的提交/索引和(通常)超级项目的 .gitmodules 文件中的一个特殊引用.在不相关的工作树中可能有其他存储库的非跟踪克隆,但这种用法不会创建子模块.
Git 1.7.0 及更高版本具有稀疏检出"功能,但将 lib 目录重新定位到每个子模块克隆的顶级目录无济于事.

* Normal submodules also require a special reference in the superproject's commits/index and (normally) an entry in the superproject's .gitmodules file. It is possible to have non-tracked clones of other repositories in an unrelated working tree, but such usage does not create a submodule.
Git 1.7.0 and later has a "sparse checkout" feature, but it would not help to relocate the lib directory the top level of each submodule clone.

然而,您可能能够使用 Git 对符号链接的支持来做一些相当接近的事情:

You might, however be able to use Git's support for symbolic links to do something that is fairly close:

#
# 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 可以拆分和合并部分存储库(即单个子目录;它是 子树合并" 与其他不错的功能).第一步是提取每个子项目中 lib 的历史记录.然后,要么直接使用提取的历史作为子模块,要么使用 git subtree 将子树合并到您的主存储库中.无论哪种方式,这都会引入一个额外的步骤(重新提取 lib 历史记录),然后才能将子项目的更改集成到主存储库中.

Using git subtree

apenwarr's git subtree can split off and merge parts of repositories (i.e. individual subdirectories; it is a wrapper around "subtree merging" with other nice features). The first step would be to extract the history of lib in each of your sub-projects. Then, either directly use the extracted history as a submodule, or use git subtree to do a subtree merge into your main repository. Either way, this would introduce an extra step (re-extracting the lib history) before you could integrate changes from a sub-project into your main repository.

这篇关于git 子模块 svn 外部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆