Git – 子树
Git 子树是 Git 子模块最常见的替代品。 Git 子树是已拖入主存储库的 Git 存储库的副本。 Git 子模块是对不同存储库中特定提交的引用。 Git 子树在 Git 1.7.11 中首次引入,可帮助您将任何 repo 的副本复制到另一个 repo 的子目录中。
子树的优点
- Git 之前的版本支持。它也支持早于 1.5 的版本。
- 工作流管理很简单。
- 超级项目完成后,会有一个可用的子项目代码。
- 你不需要更新的 Git 知识。
- 内容修改无需依赖不同的 repo。
子树的缺点
- 使用子树来构建主存储库并不是很明显。
- 您的项目的子树很难列出。
- 您不能,至少不能简单地列出子树的远程存储库。
- 当您使用子树提交更改主存储库,然后将子树提交到其主服务器,然后拉取子树时,日志可能会有点误导。
它是在 Git 项目中注入和管理项目依赖项的各种方法之一。外部依赖项存储在常规提交中。 Git 中的子树提供了干净的集成点,使恢复变得容易。当您使用 GitHub 子树教程在本地目录中创建 .gittrees 配置文件时,您不会看到子树。子树看起来是一般文件夹,但它们实际上是子存储库的副本,因此无法区分它们。 git subtree 允许您将存储库作为子目录嵌套在另一个存储库中。它是管理 Git 项目中项目依赖项的各种选项之一。您将子树添加到现有存储库,其中子树是对另一个存储库 URL 和分支/标记的引用,当您希望使用它时。这不仅仅是对远程仓库的引用;此添加命令将所有代码和文件添加到本地主存储库。
当您为主存储库暂存和提交文件时,它还将添加所有远程文件。无需链接到另一个 repo 来接收子树组件,因为子树检出将一次性获取所有文件。使用 git submodules 一段时间后,您会注意到 git subtree 修复了 git submodule 导致的许多问题。与任何与 Git 相关的东西一样,有一个学习曲线可以充分利用该功能。
假设您希望将存储库中的单个项目用作子项目。将项目复制到主仓库是标准过程。要在许多父存储库中重用子项目,将子项目克隆到每个父存储库并在每次更新时对其进行修改是不切实际的。这将导致父存储库中的冗余和不一致,从而使更新和维护子项目变得困难。
因为 Git 子树的版本与. gittrees 配置文件不包含在通常的 Git 包中,您必须从 Git 源存储库的/contrib/subtree 子目录下载 git-subtree。
您可以像任何其他通用存储库一样复制具有子树的任何存储库,但是,由于父存储库具有子存储库的完整副本,因此需要更长的时间。要在存储库中使用 Git 子树,请运行以下命令。
将子树添加到父存储库
要将新的子树添加到父存储库,首先远程添加它,然后使用 subtree add 命令,如下所示:
$ git remote add remote-name
$ git subtree add --prefix=folder/ remote-name subtree-branchname
整个子项目的提交日志被合并到主存储库中。
向子树推送和拉取更改
$ git subtree push-all
或以下命令执行如下相同:
$ git subtree pull-all
Git 子模块的存储库大小比 Git 子树小,因为它们只是指向子项目中特定提交的指针,而 Git 子树保存完整的子项目及其历史记录。 Git 中的子模块必须可以从服务器访问,而子树则不能。基于组件的开发使用 Git 子模块,而基于系统的开发使用 Git 子树。
Git 子树与 Git 子模块不同。每个可以使用的地方都有几个限制。如果您拥有一个可能会将代码推送到的外部存储库,请使用 Git 子模块,因为它更容易推送。如果存在您怀疑推送的第三方代码,请使用 Git 子树,因为它更容易拉取。您可以像这样将另一个存储库添加到此存储库中:
- 指定要添加子树。
- 表示您要添加子树。
- 指定您希望在其中拉取子树的前缀本地目录。
- 指定远程存储库的 URL [用于被拖入的子树]。
- 必须指定 [被拉入的子树的] 远程分支。
- 指定您希望从远程存储库中压缩所有 [子树] 日志。
git subtree add –prefix {local directory being pulled into} {remote repo URL} {remote branch} –squash
示例:窥视
git subtree add –prefix subtreeDirectory https://github.com/microsoft/hermes-windows master –squash
这会将 https://github.com/microsoft/hermes-windows 复制到目录 subtreeDirectory 中。
将 add 替换为 pull:如果我们希望从 main 中拉入子树的每个新贡献。
git subtree pull —prefix subtreeDirectory https://github.com/microsoft/hermes-windows master —squash