SVN:在Git中等同于外部对象?


176

我使用svn:externals从另一个SVN存储库中使用了两个SVN项目。

我如何在Git中具有相同的存储库布局结构?


您应该研究Git子模块。它应该几乎可以完全满足您的需求。
foxxtrot

7
在过去的四年中,有人对此有新的答案吗,或者今天的git世界是一样的?
DougW

4
@DougW是的,我在下面有一个新答案git submodule现在可以效仿svn:external(自2013年3月起)。
VonC

对于最新版本的Git,我建议阅读官方Git文档中的有关Git子模块的信息。
Bulki S Maslom 2015年

Answers:


134

Git有两种与svn:externals类似但不完全相同的方法:

  • 子树合并将外部项目的代码插入存储库中的单独子目录中。这有一个详细的设置过程,对于其他用户来说非常容易,因为在签出或克隆存储库时会自动包含该过程。这是在项目中包含依赖项的便捷方法。
    从另一个项目中拉取更改很容易,但是将更改提交回去很复杂。而且,如果另一个项目必须从您的代码中合并,则项目历史记录将被合并,并且两个项目实际上成为一个项目。

  • Git子模块手册)链接到另一个项目存储库中的特定提交,就像带有-r参数的svn:externals一样。子模块易于设置,但是所有用户都必须管理子模块,这些子模块不会自动包含在签出(或克隆)中。
    尽管将更改提交回另一个项目很容易,但是如果存储库已更改,这样做可能会引起问题。因此,通常不宜将更改提交回正在积极开发的项目。


17
仅供参考,现在可以使用svn:externals指定特定的修订版了(我相信是1.5还是1.6?)
Nate Parsons

9
仅供参考,git子模块可以自动管理和提交。git创建一个.gitmodules文件,可以/应该像.gitignore文件一样进行提交。有关更多信息,请参见[ git-scm.com/book/en/Git-Tools-Submodules]
mikijov 2012年

5
@NateParsons始终可以使用来指定确切的修订号svn:externals。在1.5版中,语法已更改为更灵活的格式。添加的是相对URL寻址。
David W.

@NateParsons,但是可以省略git子模块的修订版...> _>
Trejkaz

我认为不可能像svn:externals一样
搅拌

38

正如我在“ Git子模块新版本更新 ”中提到的那样,您可以使用Git 1.8.2子模块实现相同的SVN外部功能

git config -f .gitmodules submodule.<path>.branch <branch>

这足以使子模块遵循分支(如子模块上游repo的远程分支的LATEST提交)。您需要做的只是:

git submodule update --remote

这将更新子模块。

更多详细信息在“ git submodule跟踪最新 ”中。

要将现有子模块转换为一个跟踪分支的子模块,请执行以下操作:请参阅“ Git子模块:指定分支/标签 ”中的所有步骤。


您可以像这样进行部分结帐svn:externals吗?
nowox

@nowox是的,您可以拥有与子模块(stackoverflow.com/a/17693008/6309)相关联的稀疏签出(git 1.7+ stackoverflow.com/a/2372044/6309)–
VonC

不幸的是,所有与稀疏结帐有关的答案都从未给出任何示例:(我将尝试为此编写一个Gist示例...
nowox

仍然有一个问题。您仍然必须获得存储库的全部历史记录,而您只需要一小部分。我的情况是2GB超过100kB。我当然可以使用,--depth但是并不能真正解决问题。
nowox

@nowox最好提出一个新问题,以确切说明您的用例是什么:我不知道您的2GB存储库是子模块还是带子模块的主存储库,以及您究竟需要从中提取什么。
VonC

3

我是gil(git链接)工具的作者

我有一个替代的解决方案-gil(git links)工具

它允许描述和管理复杂的git仓库依赖性。

它还为git递归子模块依赖问题提供了解决方案。

考虑您具有以下项目依赖项: 样本git信息库依赖关系图

然后,您可以.gitlinks使用存储库关系描述定义文件:

# Projects
CppBenchmark CppBenchmark https://github.com/chronoxor/CppBenchmark.git master
CppCommon CppCommon https://github.com/chronoxor/CppCommon.git master
CppLogging CppLogging https://github.com/chronoxor/CppLogging.git master

# Modules
Catch2 modules/Catch2 https://github.com/catchorg/Catch2.git master
cpp-optparse modules/cpp-optparse https://github.com/weisslj/cpp-optparse.git master
fmt modules/fmt https://github.com/fmtlib/fmt.git master
HdrHistogram modules/HdrHistogram https://github.com/HdrHistogram/HdrHistogram_c.git master
zlib modules/zlib https://github.com/madler/zlib.git master

# Scripts
build scripts/build https://github.com/chronoxor/CppBuildScripts.git master
cmake scripts/cmake https://github.com/chronoxor/CppCMakeScripts.git master

每行以以下格式描述git链接:

  1. 存储库的唯一名称
  2. 存储库的相对路径(从.gitlinks文件的路径开始)
  3. Git仓库将在git clone命令仓库分支中使用以结帐
  4. 空行或以#开头的行不会被解析(视为注释)。

最后,您必须更新您的根样本存储库:

# Clone and link all git links dependencies from .gitlinks file
gil clone
gil link

# The same result with a single command
gil update

结果,您将克隆所有必需的项目,并以适当的方式将它们彼此链接。

如果要使用子链接存储库中的所有更改来提交某个存储库中的所有更改,则可以使用单个命令来执行此操作:

gil commit -a -m "Some big update"

拉,推命令的工作方式类似:

gil pull
gil push

Gil(git链接)工具支持以下命令:

usage: gil command arguments
Supported commands:
    help - show this help
    context - command will show the current git link context of the current directory
    clone - clone all repositories that are missed in the current context
    link - link all repositories that are missed in the current context
    update - clone and link in a single operation
    pull - pull all repositories in the current directory
    push - push all repositories in the current directory
    commit - commit all repositories in the current directory

有关git递归子模块依赖问题的更多信息。


1
您应该在帖子顶部放一个免责声明,说您是的作者gil
Daniel Kamil Kozar
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.