ChatGPT解决这个技术问题 Extra ChatGPT

SVN:Git 中的外部等效项?

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

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

您应该查看 Git submodules。它应该几乎完全符合您的要求。
在过去的 4 年里,有人对此有新的答案,还是今天的 git 世界也一样?
@DougW 是的,我有一个 new answer belowgit submodule 现在可以模拟 svn:external(自 2013 年 3 月起)。
对于最新版本的 Git,我建议阅读官方 Git 文档中的 Git submodules

T
The Godfather

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

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

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


仅供参考,现在可以使用 svn:externals 指定特定的修订版(我相信从 1.5 或 1.6 开始?)
仅供参考,git 子模块可以自动管理和提交。 git 创建一个 .gitmodules 文件,该文件可以/应该像 .gitignore 文件一样提交。有关详细信息,请参阅 [git-scm.com/book/en/Git-Tools-Submodules]
@NateParsons 始终可以使用 svn:externals 指定确切的修订号。在 1.5 版中,语法被更改为更灵活的格式。添加的是相对 URL 寻址。
@NateParsons 但是否可以使用 git 子模块省略修订...>_>
这听起来几乎像茶,但并不完全不同。
P
Peter Mortensen

正如我在“Git submodule new version update”中提到的,您可以使用 Git 1.8.2 子模块实现相同的 SVN 外部功能

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

这足以让子模块跟随分支(如子模块 upstream repo 的远程分支的最新提交)。您需要做的就是:

git submodule update --remote

这将更新子模块。

更多详细信息在“git submodule tracking latest”中。

要将现有的子模块转换为跟踪分支的子模块:请参阅“Git submodules: Specify a branch/tag”中的所有步骤。


您可以像使用 svn:externals 那样进行部分结帐吗?
@nowox 是的,您可以将稀疏结帐(git 1.7+ stackoverflow.com/a/2372044/6309)关联到子模块(stackoverflow.com/a/17693008/6309
不幸的是,所有与结帐相关的稀疏答案都没有给出任何示例:(我将尝试为此编写一个 Gist 示例...
这仍然存在问题。您仍然需要获取只需要一小部分的存储库的全部历史记录。在我的情况下是 100kB 超过 2GB。我当然可以使用 --depth,但它并不能真正解决问题。
@nowox 最好问一个新问题,准确解释您的用例是什么:我不知道您的 2GB 存储库是子模块还是带有子模块的主存储库,以及您需要从中提取什么。
c
chronoxor

我是 gil (git links) 工具的作者

我有解决该问题的替代方案 - gil (git links) tool

它允许描述和管理复杂的 git 存储库依赖项。

它还为 git recursive submodules dependency problem 提供了解决方案。

假设您有以下项目依赖项:sample git repository dependency graph

然后您可以使用存储库关系描述定义 .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 链接:

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

最后,您必须更新您的根示例存储库:

# 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 links) 工具支持以下命令:

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 recursive submodules dependency problem 的更多信息。


您应该在帖子顶部放置免责声明,说明您是 gil 的作者。