记一下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
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《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年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!