背景:
历史原因git分支合并到主干git分支合并到主干,拆分了 20 几个仓库出来,仓库太多而人员太少,没有人维护项目分支的管理
Git分支的成本太廉价,创建且不删除的代价很小
Windows上的 GUI 工具太给力,轻易就能搜索对应的分支,但在Linux下GitGUITools没什么很好的工具
开发人员没有良好的习惯,自己创建的分支经常不删除、经常在过期的迭代分支调试代码…
一般我自己开发完需求会清理掉这类分支,但是耐不住长期下来的积累,分支泛滥,最严重的一个历史项目居然积压了 256 个无效分支。目前后端团队就 10+ 来人,95% 的分支估计都是没什么用的!
很多已经合并到了 origin/master 没有删除,很多虽然没有合并到 origin/master 但最后一次提交都要追溯到 2018-2022 年期间去了。
写一个脚本完成以下目标:
自动拉取最新稳定项目的主干分支(master)
清除本地已经丢失了的远程追踪的分支及其远程追踪记录
提醒对应的开发人员及时清理已经合并到了 origin/master 的远程分支
提醒对应的开发人员及时清理已经远远落后 origin/master 的远程分支
上述操作在 GitLab 下也可以操作一部分,但是…需要人去点,还要有权限才能删除。一个个项目这么点…
清明假期间写了一个脚本,自动清理 1100+ 个分支。
很久没发文,保号发一篇,脚本如下:
#title : git-branch-alert
#description : Git 已合并/过期分支清理提醒脚本
#author : limingshuang
#date : 2023/04/05
#version : 1.0
#===============================================
# 定义项目目录
project_path='/mnt/d/htdocs'
if [ $1 ];then
project_path=$1
fi
# 定义默认检查最深目录层级
level=4
if [ $2 ];then
level=$2
fi
# 定义过期分支时间参数,默认:非当前年的分支都视为过期分支
timeReg=$(date +%Y);
if [ $3 ];then
timeReg=$3
fi
# 定义 log 输出文件
log='/tmp/project-branch-alert-log_'$(date +%Y%m%d)'.log'
if [ ! -a $log ]; then
touch $log
echo -e "创建 $logn"
fi
cat /dev/null > $log
# 定义主干远程分支, 一般都为 master,Github 现在为了避嫌改为了 main
master='master'
# 定义通用 Git命令
keepBranch='dev|master|main|HEAD|->'
# 自动拉取当前分支
fb='git pull $(git remote) $(git symbolic-ref --short -q HEAD)'
# 检查远程分支列表中,有哪些远程分支是没有合并到当前所指向的远程分支的
cm='git branch -r --merged $(git remote)/$(git symbolic-ref --short -q HEAD) | grep -vE "$keepBranch"'
# 检查过期分支命令定义
cv='git for-each-ref refs/remotes/ --format="%(refname:short) %(authorname) (%(committerdate:short))" | grep -Ev "$keepBranch|$timeReg"'
function action()
{
echo -e "n更新:$1"
# reset 当前工作域自动 fetch 远程信息
cd $1 && git reset --hard HEAD && git fetch -pa $(git remote) && git worktree prune
# fix:处理 github 仓库将 master 改为 main,导致上游分支丢失问题
# 自动将本地 master 切换为 main 分支
if [[ `git symbolic-ref --short -q HEAD` = 'master' && `git branch -r | grep origin/main | wc -l` != 0 ]];then
master='main'
elif [[ `git symbolic-ref --short -q HEAD` != 'master' && `git branch -r | grep origin/master | wc -l` != 0 ]];then
master='master'
fi
# 先更新当前分支,然后切到主分支, 更新主干分支
eval $fb
if [[ `git symbolic-ref --short -q HEAD` != $master ]];then
git switch $master && eval $fb
fi
# 清理本地已经丢失了远程分支的分支
git branch -v | grep -F [gone] | awk '{print $1}' | xargs -I {} bash -c "if [ ! -z {} ];then git branch -D {};fi"
# 检查没有合并到当前分支所在远程分支
local cmLog='';cmLog=$(eval $cm)
if [ ! -z "$cmLog" ];then
echo -e "n已经合并到 - "$(git remote)/$(git symbolic-ref --short -q HEAD)"分支($1# " $(git remote get-url --push $(git remote))"),请及时清理:n$cmLog" >> $log
fi
# 检查过期分支
local cvLog='';cvLog=$(eval $cv)
if [ ! -z "$cvLog" ];then
echo -e "n过期分支 - "$(git remote)/$(git symbolic-ref --short -q HEAD)"($1# " $(git remote get-url --push $(git remote))"),请相关人员检查并清理:n$cvLog" >> $log
fi
# 如果存在子模块,则同步更新子模块
if [ -f "$1/.gitmodules" ];then
git submodule update --init --remote --recursive && git submodule foreach 'echo "清理 $sm_path" && git fetch -pa $(git remote)'
fi
}
function listDir()
{
local project_path=$1;
# 如果传入目录已经是一个 Git 项目直接执行更新退出
if [ -d "$project_path/.git" ];then
action $project_path
if [ $(echo $project_path | grep "/library" | wc -l) -eq 1 ] && [ -d "$project_path/erc-model" ]; then
action $project_path/erc-model
fi
return
fi
# 如果不是 Git 目录
for dir in `ls -l $project_path/ | grep -E "^d" | awk '{print $NF}' | grep -v "vendor"`;
do
local l=$2
# 判断目录层级
if [ $l -le $level ] && ((l+=1));then
listDir $project_path/$dir $l
fi
done
}
listDir $project_path 1
将脚本拷贝到 /usr/local/bin 下,创建脚本名为:git-branch-alert,使用 git-branch-alert
!!!注意:使用这个脚本之前记得先提交你项目目录的记录,因为脚本中的 git reset–hard HEAD 会清掉你当前工作区的信息。
最后的效果如下图(当然你可以加上自己的企业机器人到群里提醒大家处理,这部分逻辑我删除掉了,需要自己加一下就好):
限时特惠:本站每日持续更新海量展厅资源,一年会员只需29.9元,全站资源免费下载
站长微信:zhanting688