「译文」Git subtree: Git submodule 的替代品

简介: 「译文」Git subtree: Git submodule 的替代品

👉️URL: https://www.atlassian.com/git/tutorials/git-subtree

✍️Author: Nicola Paolucci

📝Description:

Git subtree 让你把一个仓库嵌套在另一个子目录中。它是 Git 可以管理项目依赖关系的几种方式之一。

git 分支的图解

互联网上有很多关于为什么你不应该使用 Git submodule 的文章。虽然 submodule 在一些使用情况下很有用,但它们确实有一些缺点。

有替代品吗?答案是:有!有(至少)两个工具可以帮助跟踪你项目中的软件依赖历史,同时允许你继续使用 Git。

  • git subtree
  • Google repo

在这篇文章中,我们将看看git subtree,并说明为什么它比 git submodule 有进步–尽管不是很完美。

什么是git subtree,我为什么要使用它?

git subtree让你把一个仓库嵌套在另一个子目录中。它是 Git 项目管理项目依赖关系的几种方式之一。

图中显示了使用 Git Subtree 前后两个仓库之间的互动

为什么你可能要考虑git subtree

  • 简单工作流的管理很容易。
  • 支持老版本的 Git(甚至比 v1.5.2 更老)。
  • 子项目的代码在父级项目的克隆完成后就可以使用。
  • git subtree不需要你的仓库的用户学习任何新东西。他们可以忽略你使用 git subtree 来管理依赖关系的事实。
  • git subtree不会像 git submodule 那样添加新的元数据文件(即.gitmodule)。
  • 模块的内容可以被修改,而不需要在其他地方有单独的依赖关系的仓库副本。

缺点(但在我们看来,这些缺点基本可以接受)。

  • 你必须学习新的合并策略(即 git subtree)。
  • 为子项目向上游贡献代码稍显复杂。
  • 在提交中不混合父级项目和子项目代码的责任在于你。

如何使用 git subtree

git subtree自 2012 年 5 月起在 Git 的库存版本中可用 - v1.7.11 及以上。homebrew 软件在 OSX 上安装的版本已经将 subtree 正确地连接起来,但在某些平台上,你可能需要按照安装说明进行安装。

下面是一个使用git subtree. tracking vim 插件的典型例子。

没有 remote tracking 的快速和肮脏的方法

如果你只想剪切和粘贴几句单句,请阅读这一段。首先在指定的前缀文件夹下添加git subtree

git subtree add --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash
BASH

(通常的做法是不把子项目的全部历史保存在主版本库中,但如果你想保存它,只需省略 --squash 标志)。

上述命令产生了这样的输出。

git fetch https://bitbucket.org/vim-plugins-mirror/vim-surround.git main
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (145/145), done.
remote: Total 338 (delta 101), reused 323 (delta 89)
Receiving objects: 100% (338/338), 71.46 KiB, done.
Resolving deltas: 100% (101/101), done.
From https://bitbucket.org/vim-plugins-mirror/vim-surround.git
* branch main -} FETCH_HEAD
Added dir '.vim/bundle/tpope-vim-surround'
BASH

正如你所看到的,这是通过将 vim-surround 版本库的全部历史压缩成一个单一的历史来记录一个合并提交。

1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as '.vim/bundle/tpope-vim-surround' [Nicola Paolucci]
ca1f4da [3 minutes ago] Squashed '.vim/bundle/tpope-vim-surround/' content from commit 02199ea [Nicola Paolucci]
N1QL

如果过了一段时间,你想从上游仓库更新插件的代码,你可以只做一个 git subtree pull。

git subtree pull --prefix .vim/bundle/tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git main --squash
BASH

这是非常快速和无痛的,但命令略显冗长,难以记忆。我们可以通过添加子项目作为 remote 来使命令更短。

将子项目添加为 remote

将 subtree 作为一个 remote 添加,可以让我们以更短的形式来引用它。

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
VIM

现在我们可以添加 subtree(和以前一样),但现在我们可以用简短的形式来引用远程。

git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash
VIM

以后更新子项目的命令变成:

git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash
CSS

回馈上游

现在我们可以自由地提交我们的修正到本地工作目录中的子项目。当需要向上游项目做出贡献时,我们需要分叉该项目并将其作为另一个远程项目。

git remote add durdn-vim-surround ssh://git@bitbucket.org/durdn/vim-surround.git
BASH

现在我们可以像下面这样使用子树推送命令。

git subtree push --prefix=.vim/bundle/tpope-vim-surround/ durdn-vim-surround main
git push using: durdn-vim-surround main
Counting objects: 5, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 308 bytes, done.
Total 3 (delta 2), reused 0 (delta 0)
To ssh://git@bitbucket.org/durdn/vim-surround.git
02199ea..dcacd4b dcacd4b21fe51c9b5824370b3b224c440b3470cb -} main
BASH

在这之后,我们就准备好了,我们可以向软件包的维护者发出 pull-request。

我可以不使用 git subtree 命令来做这个吗?

是的!是的,可以。git subtree与 subtree merge 策略不同。即使由于某种原因 git subtree 不可用,你仍然可以使用合并策略。以下是你如何去做的。

将依赖关系作为一个简单的 git remote 添加。

git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
BASH

在将依赖关系的内容读入版本库之前,记录一个合并是很重要的,这样我们就可以跟踪到此为止的整个插件树历史。

git merge -s ours --no-commit tpope-vim-surround/main
BASH

输出为:

Automatic merge went well; stopped before committing as requested
BASH

然后,我们将最新的 tree-object 的内容读入插件库,进入我们的工作目录,准备提交。

git read-tree --prefix=.vim/bundle/tpope-vim-surround/ -u tpope-vim-surround/main
BASH

现在我们可以提交了(这将是一个合并提交,将保留我们所读的树的历史)。

git ci -m"[subtree] adding tpope-vim-surround"
[stree 779b094] [subtree] adding tpope-vim-surround
BASH

当我们想更新项目时,我们现在可以使用 git subtree 合并策略进行拉动。

git pull -s subtree tpope-vim-surround main
CSS

Git subtree是一个很好的选择

在使用了一段时间的 git submodule 之后,你会发现 git subtree 解决了很多 git submodule 的问题。像往常一样,对于所有 Git 的东西,要想充分利用这个功能,都有一个学习曲线。

在 Twitter 上关注我 @durdn,了解更多关于 Git 的事情和东西。如果你正在寻找一个好的工具来管理你的 Git 仓库,请查看 Atlassian Bitbucket。

相关文章
|
2月前
|
存储 Linux 开发工具
「译文」使用 submodule 和 subtree 管理 Git 项目
「译文」使用 submodule 和 subtree 管理 Git 项目
|
2月前
|
存储 开发工具 git
将 git 仓库从 submodule 转换为 subtree
将 git 仓库从 submodule 转换为 subtree
|
5天前
|
开发工具 git
Git教程:深入了解删除分支的命令
【4月更文挑战第3天】
32 0
Git教程:深入了解删除分支的命令
|
23天前
|
存储 Shell Linux
【Shell 命令集合 文件管理】Linux git命令使用教程
【Shell 命令集合 文件管理】Linux git命令使用教程
31 0
|
23天前
|
开发工具 git
git常用命令整理
git常用命令整理
13 0
|
11天前
|
开发工具 git 开发者
Git常用命令大全:让你轻松驾驭版本控制
Git命令速查:`git init`新建仓库,`git clone`克隆,`git add`入暂存区,`git commit -m`提交,`git status`查看状态,`git log`查看历史,`git branch`创建分支,`git checkout`切换,`git merge`合并,`git pull`拉取更新,`git push`推送,`git remote -v`查看远程,`git checkout --`撤销本地修改,`git reset HEAD`取消暂存,`git reset --hard`回退版本。掌握这些,提升代码管理效率!
14 0
|
3月前
|
测试技术 持续交付 开发工具
1.Git使用技巧-常用命令3
1.Git使用技巧-常用命令3
34 0
|
1天前
|
缓存 数据可视化 网络安全
Git命令大全
Git命令大全
9 1
|
18天前
|
算法 开发工具 git
【git 实用指南】git 增加 本地代码 git add 相关命令和复杂情况需求
【git 实用指南】git 增加 本地代码 git add 相关命令和复杂情况需求
89 0
|
22天前
|
Shell Linux 开发工具
【Shell 命令集合 系统管理 】Linux 查看当前Git仓库的提交历史 gitps命令 使用指南
【Shell 命令集合 系统管理 】Linux 查看当前Git仓库的提交历史 gitps命令 使用指南
14 0