git submodule svn external [英] git submodule svn external

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

问题描述

假设我有3个git仓库,每个仓库在根目录下都有一个 lib tests 文件夹。所有3个仓库都是我希望成为单一软件包的一部分,但对我来说保持仓库是分开的是非常重要的。



我是新来的sit来自svn ,所以我一直在阅读子模块以及它们与 svn:externals 的区别。在SVN中,我可以有一个单独的

$ $ p $ lib / vendor / package

目录,并且在 package中我可以设置3个外部指向我的每个3个存储库 lib 目录,重新命名为

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

但是从我的理解来看,这对于git来说是不可能的。我错过了什么?



真的,我希望这可以通过以下两种方式之一来解决。


  1. 有人会指出如何创建一个第4个git仓库,其中有3个作为子模块,就像我上面提到的那样(我可以有一个 a b ,和 c 根目录中的文件夹)

  2. 有人会指出如何使用 svn:externals 与githubs svn support结合使用,引用每个目录中的 lib 目录git仓库(根据我的理解,这是不可能的)



更新:



我实际上已经尝试了跟你链接的子模块教程,但我遇到了以下问题。



执行上面所示的操作,而不是象

  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

从现在开始访问 ClassA 里面 repo1 lib 文件夹,路径是

  lib / vendor / package / a / lib / ClassA 

当我真的试图得到(这可能与svn:externals)

  lib / vendor / package / a / ClassA 

因为上面的 a 实际上是 repo1 / lib ,而不是 repo1

的根目录。

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

  \Package\a\ClassA  - > lib / vendor / package / a / ClassA 

这是我的概念误解所在,如何设置第四个git仓库允许我的目录映射如上所示。

解决方案

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



有几种间接方法可以完成你想要的功能。



使用子模块和符号链接



核心Git子模块是超级项目 * 的工作树中另一个存储库的克隆。
Git仅克隆完整存储库。无法从现有存储库中克隆一个子目录。


$ b * 正常的子模块在超级项目的提交/索引和(通常)超级项目的 .gitmodules 文件中需要一个特殊的引用。
可以在不相关的工作树中使用其他存储库的未跟踪克隆,但此类使用不会创建子模块。

Git 1.7.0并且稍后有一个稀疏结帐功能,但它无助于将 lib 目录重定位到每个子模块克隆的顶层。



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

 
#使每个子模块的lib目录出现在超级项目中
#lib / vendor / packages / $ submod_name

#在每个子模块中使用此结构(a,b,c):

#lib /
#tests /

#我们在超级项目中得到这个结构:

#lib /
#vendor /
#packages /
#a(与../../../_submodules/a/lib的符号链接)
#b(到../../../_submodules/b/lib的符号链接)
# c(一个到../../../_submodules/c/lib的符号链接)
#_submodules
#a /(一个Git子模块)
#lib /
#测试/
#b /(一个Git子模块)
#lib /
#tests /
#c /(一个Git子模块)
#lib /
#tests /

add_one(){
dir = lib / vendor / package
dest =$ dir / $ 1
#use less..将子模块放在符号链接附近
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 subtree



apenwarr's git subtree 可以拆分并合并部分存储库(即,个别子目录;它是一个围绕子树合并的包装与其他不错的功能)。第一步是在每个子项目中提取 lib 的历史记录。然后,直接使用提取的历史记录作为子模块,或者使用 git subtree 将子树合并到主存储库中。无论哪种方式,这将引入额外的步骤(重新提取 lib 历史记录),然后才能将子项目的更改集成到主存储库中。


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.

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

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

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. 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

I am left with

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

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

lib/vendor/package/a/lib/ClassA

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

lib/vendor/package/a/ClassA

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

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

\Package\a\ClassA  -> lib/vendor/package/a/ClassA

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

解决方案

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.

Using Submodules and Symlinks

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.

* 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.

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

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 submodule svn external的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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