Git Subtree

By | 7月 17, 2026

Git Subtree 比 Submodule 好一些,虽然也并不完美。

  • Git subtree 直接把 子仓库 的内容保存下来了。
  • 它没有像 submodule 那样的 metadata 文件(.gitmodules);user 也不需要有 sub project repo 的访问权限。
  • 主仓库的 user 不用学习 git subtree,甚至感觉不到 主仓库 用 subtree 管理某个依赖。

缺点:

  • 不能列出 repo 中的所有 subtree 对应的所有 folders。
  • 反向更新 sub project 到 upstream 有点慢。
  • 需要自己管理每个 subtree 和哪个 remote repository 关联。

使用 subtree 的命令

添加 sub project

通常加上 --squash ,减少 sub project commits 对 super project 的污染。

git subtree add --prefix {relative-folder} {GitUrl or RemoteReference} {BranchName or TagName} --squash
// example
git remote add -f tpope-vim-surround https://bitbucket.org/vim-plugins-mirror/vim-surround.git
git subtree add --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround main --squash

从 upstream 更新 sub project

把上面的 subtree add 换成 subtree pull。例如拉取 upstream release/v1.4.0 content。

git fetch tpope-vim-surround main
git subtree pull --prefix .vim/bundle/tpope-vim-surround tpope-vim-surround release/v1.4.0 --squash

sub project 的改动反向更新回 upstream

下面命令会在 upstream 创建一个新的 branch,时间比较长。因为 sub project 和 upstream 的 commit history 不一样,所有内容都会上传上去。等 branch 创建好,就可以发 pull-request。

git subtree push --prefix .vim/bundle/tpope-vim-surround durdn-vim-surround {new-branch-name}