记一下git subtree搭配split-item分包的用法

前言#

一直挺好奇像 laravel hyperf 这些框架的主仓库怎么都是 src 目录下放着所有的 library ,合并也是往主仓库提 pr。子仓库就能达到同步更新了。问了问一些佬,外加自己看了看 这些仓库里面的 bin/split-linux.sh 代码,勉强能理解了,记录一下场景。如果有什么地方不对希望各位能提示补充一下


#涉及的工具和知识点


  • splite-item
  • git subtree(好像也不用,看后言)

场景#


laravel tp hyperf 这种框架,library 那么多
如果每个仓库都单独来进行版本维护,意味着每次一个 tag 发布
都要切换无数个仓库挨个挨个去 push tag
一听都要感觉头皮发麻,而且每个 library 有些都互相依赖
开发调试就够喝一壶的

分包原理#

其实也简单,搭配 split-item 脚本将指定的目录分包,再加上自己定义的部署脚本就能实现,
这里上一下 hyperf 的 split-linux.sh

#!/usr/bin/env bash
# 如果任何语句的退出状态不是 0,立即退出脚本。确保一旦发生错误就停止执行
set -e
# 在执行每一条命令之前,先打印出该命令及其参数
set -x

# 执行()内的命令,获取当前的分支
CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
# 执行 命令行参数第一个参数,获取src绝对路径
BASEPATH=$(cd `dirname $0`; cd ../src/; pwd)
# 将所有参数赋值给 repos
REPOS=$@

# 这里是调用splitsh-lite-linux传入--prefix参数拆分目录作为子模块,并且将结果sha1传入到变量内,接着调用 git push 向远程仓库指定分支强制push代码
function split()
{
    SHA1=`./bin/splitsh-lite-linux --prefix=$1`
    git push $2 "$SHA1:refs/heads/$CURRENT_BRANCH" -f
}
# 添加远程仓库
function remote()
{
    git remote add $1 $2 || true
}
# 这里是实际第一行代码,先从远程仓库获取最新的代码
git pull origin $CURRENT_BRANCH

# 判断命令行参数数量,如果为空就获取src目录下所有目录名称传入到repos变量内
if [[ $# -eq 0 ]]; then
    REPOS=$(ls $BASEPATH)
fi

# for循环获取子模块,调用remote、split函数去完成推送子仓库操作
for REPO in $REPOS ; do
    remote $REPO git@github.com:hyperf/$REPO.git

    split "src/$REPO" $REPO
done

后言#

到这里基本就完事了,有一点不太明白,我可以用 git subtree add 一个个去加子库
也可以不事先用 git subtree,直接把新建的目录作为子仓库直接 push. 两种方式
一般哪种比较符合规矩

本作品采用《CC 协议》,转载必须注明作者和本文链接
这片绿茵从不缺乏天才,努力才是最终的入场券
zds
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 6
mouyong

仓库自动分离出子仓库 github.com/mouyong/monorepo-split

可以了解了解。让你的任何仓库都可以根据文件夹分理出子仓库。

1年前 评论
mouyong

都是基于这个做的子仓库自动分离。

1年前 评论
zds

@mouyong 这个分包我能理解,只是我自己发现有两种方式,一种是 git subtree add, 还有一种就是子目录直接分离。不太清楚这两种哪种比较符合规矩

1年前 评论
mouyong 1年前
mouyong

推荐你使用目录分割的方式。这样不用一个个的 subtree add 和 subtree split

1年前 评论
zds

@mouyong 好的,谢谢佬,记住了

1年前 评论