問題描述
假設(shè)我有 3 個(gè) git 存儲(chǔ)庫,每個(gè)存儲(chǔ)庫在根目錄中都有一個(gè) lib
和 tests
文件夾.所有 3 個(gè)存儲(chǔ)庫都是我希望成為單個(gè)包的一部分,但是將存儲(chǔ)庫分開對(duì)我來說很重要.
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
的區(qū)別.在 SVN 中,我可以有一個(gè)
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
內(nèi)部,我可以設(shè)置 3 個(gè)外部文件,指向我的 3 個(gè)存儲(chǔ)庫中的每一個(gè) lib
目錄,將其適當(dāng)重命名為
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
但據(jù)我所知,這在 git 中是不可能的.我錯(cuò)過了什么嗎?
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.
- 有人會(huì)指出如何創(chuàng)建第 4 個(gè) git 存儲(chǔ)庫,該存儲(chǔ)庫將其他 3 個(gè)作為子模塊組織起來,如我上面提到的(我可以在其中擁有
a
、b
, 和c
文件夾內(nèi)的根目錄) - 有人會(huì)指出如何使用
svn:externals
結(jié)合 githubs svn 支持進(jìn)行設(shè)置,引用每個(gè) git 存儲(chǔ)庫中的lib
目錄(根據(jù)我的理解不可能)
- 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
, andc
folder inside the root) - Someone will point out how to set this up using
svn:externals
in combination with githubs svn support, referencing thelib
directory within each git repository (from my understanding this is impossible)
更新:
我實(shí)際上曾嘗試按照您鏈接的子模塊教程進(jìn)行操作,但遇到了以下問題.
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
這并不理想,因?yàn)楝F(xiàn)在訪問repo1
的lib
文件夾中的ClassA
,路徑是
this is not ideal since now to access ClassA
inside repo1
's lib
folder, the path is
lib/vendor/package/a/lib/ClassA
當(dāng)我真的想得到(這可以通過 svn:externals 實(shí)現(xiàn))
when I'm really trying to get (and this is possible with svn:externals)
lib/vendor/package/a/ClassA
因?yàn)樯厦娴?code>a實(shí)際上是repo1/lib
,而不是repo1
的根目錄.
since a
above is actually repo1/lib
, and not the root directory of repo1
.
這樣的事情很重要,因?yàn)橐?PHP5.3
為例,使用 SplClassLoader
( http://gist.github.com/221634 ),它需要一個(gè)命名空間到目錄的映射,如
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
這是我概念性誤解的地方,如何設(shè)置第 4 個(gè) git 存儲(chǔ)庫以允許我的目錄映射如上.
this is where my conceptual misunderstanding is, how to setup that 4th git repository to allow my directory mappings like above.
推薦答案
你說得對(duì),Git 子模塊不能直接做你想做的事.它在 SVN 中工作,因?yàn)榇鎯?chǔ)庫的根、分支及其任何子目錄都是同一種對(duì)象.在 Git 中,存儲(chǔ)庫、分支和目錄都是不同類型的對(duì)象(您不能將目錄用作完整存儲(chǔ)庫或分支).
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).
不過,有幾種間接方法可以實(shí)現(xiàn)您的愿望.
There are a couple of indirect ways to accomplish what you want though.
Git 子模塊的核心是超級(jí)項(xiàng)目"的工作樹中另一個(gè)存儲(chǔ)庫的克隆*.Git 只克隆完整的存儲(chǔ)庫.不可能從現(xiàn)有存儲(chǔ)庫中只克隆一個(gè)子目錄?.
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?.
* 普通子模塊還需要在超級(jí)項(xiàng)目的提交/索引和(通常)超級(jí)項(xiàng)目的 .gitmodules
文件中的一個(gè)特殊引用.在不相關(guān)的工作樹中可能有其他存儲(chǔ)庫的非跟蹤克隆,但這種用法不會(huì)創(chuàng)建子模塊.
? Git 1.7.0 及更高版本具有稀疏檢出"功能,但將 lib
目錄重新定位到每個(gè)子模塊克隆的頂級(jí)目錄無濟(jì)于事.
* 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 對(duì)符號(hào)鏈接的支持來做一些相當(dāng)接近的事情:
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 可以拆分和合并部分存儲(chǔ)庫(即單個(gè)子目錄;它是 子樹合并" 與其他不錯(cuò)的功能).第一步是提取每個(gè)子項(xiàng)目中 lib
的歷史記錄.然后,要么直接使用提取的歷史作為子模塊,要么使用 git subtree 將子樹合并到您的主存儲(chǔ)庫中.無論哪種方式,這都會(huì)引入一個(gè)額外的步驟(重新提取 lib
歷史記錄),然后才能將子項(xiàng)目的更改集成到主存儲(chǔ)庫中.
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.
這篇關(guān)于git 子模塊 svn 外部的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!