Git 子仓库

217 阅读3分钟

在进行项目开发和管理的过程中,您可能会遇到这种情况:您自己的 A 项目需要引用另一个 B 项目中的内容,直接将 B 项目中的文件克隆合并到 A 项目中显得臃肿,不能保证两者的独立性;此外,直接克隆合并的方法也无法记录对于 B 项目的改动信息。

Tips:其他项目管理方式

  • 将子项目上传至 npm 库或者上传至私有 npm 库
  • Monorepo 模式

目前 Git 添加子仓库的方式有两种

Pasted image 20230204210622.png

submodule和subtree区别.excalidraw.svg

git submodule

  • 子项目作为一个独立的仓库,可以单独提交,但是不会被包含在父项目的仓库中,只是作为一个引用
    • 会在父项目的.gitmodules文件中记录子项目的信息
    • 会在.git/config文件中记录子项目的信息
    • 会在父项目的.git/modules目录下创建子项目的仓库
    • 使用git clone --recursive <父项目仓库 url>可以递归克隆子项目
    • 使用git add <url> <path>可以克隆添加子项目
    • 使用git submodule update --init可以更新子项目
    • 使用git submodule update --init --recursive可以递归更新子项目
    • 使用git submodule update --remote可以更新子项目到最新版本
    • 如何删除子git submodule
      • 删除.gitmodules文件中的子项目信息
      • 删除.git/config文件中的子项目信息
      • 删除.git/modules目录下的子项目仓库
      • 删除父项目中的子项目目录
# 添加子仓库
git submodule add <url> <path>
# 添加子仓库并指定分支
git submodule add -b <branch> <url> <path>
# 更新子仓库
git submodule update --init --recursive
# 删除子仓库
git submodule deinit <path>
git rm <path>
# 删除 .gitmodules 文件中的子仓库信息
git config -f .gitmodules --remove-section submodule.<path>

git subtree

  • 不像 git submodule,子项目不是一个独立的仓库,而是作为父项目的一个目录
  • 添加子项目时,会将子项目作为一个分支添加到父项目中
  • 完全像拉取一个分支一样,合并子项目到父项目中
  • 没有 .gitmodules 文件,记录子项目信息,完全不知道子项目的存在
  • 使用
    • 使用git subtree add --prefix <path> <url> <branch> --squash可以添加子项目
    • --squash可选参数:表示将子库的所有提交合并为一个提交,这样可以避免子库的提交历史污染主库
    • 使用git subtree pull --prefix <path> <url> <branch> --squash可以从子项目更新父项目
    • 使用git subtree push --prefix <path> <url> <branch>可以从父项目更新子项目
    • 使用git subtree split --prefix <path> -b <branch>可以将子项目分离出来作为一个独立的仓库
    • 使用git subtree merge --prefix <path> <branch>可以将分离出来的子项目合并到父项目中
  • 如何删除git subtree
    • 删除父项目中的子项目目录
    • 删除父项目中的子项目分支
# 添加子仓库
git subtree add --prefix <path> <url> <branch> --squash
# 更新子仓库
git subtree pull --prefix <path> <url> <branch> --squash
# 更新父仓库
git subtree push --prefix <path> <url> <branch>
# 分离子仓库
git subtree split --prefix <path> -b <branch>
# 合并子仓库
git subtree merge --prefix <path> <branch>

个人使用小结

  • git submodule:好使推荐使用,子项目完全独立,有完整的子项目信息,独立管理,GUI 工具支持较好
  • git subtree:项目复杂度高的项目使用或许有不错的效果,和操作分支那样但是操作复杂,但是无子项目信息,不独立管理,GUI 工具支持较差,命令复杂
    • 比较灵活,需要较好的项目管理能力,手动维护子项目信息
    • 建议写个脚本,自动维护子项目信息

简单的来说,git submodule 是引用,git subtree 是复制

目前个人没有使用 git subtree 的场景,所以不太清楚 git subtree 对比 git submodule 的优势在哪里

参考