背景:

历史原因git分支合并到主干git分支合并到主干,拆分了 20 几个仓库出来,仓库太多而人员太少,没有人维护项目分支的管理

Git分支的成本太廉价,创建且不删除的代价很小

Windows上的 GUI 工具太给力,轻易就能搜索对应的分支,但在Linux下GitGUITools没什么很好的工具

开发人员没有良好的习惯,自己创建的分支经常不删除、经常在过期的迭代分支调试代码…

一般我自己开发完需求会清理掉这类分支,但是耐不住长期下来的积累,分支泛滥,最严重的一个历史项目居然积压了 256 个无效分支。目前后端团队就 10+ 来人,95% 的分支估计都是没什么用的!

很多已经合并到了 origin/master 没有删除,很多虽然没有合并到 origin/master 但最后一次提交都要追溯到 2018-2022 年期间去了。

写一个脚本完成以下目标:

自动拉取最新稳定项目的主干分支(master)

清除本地已经丢失了的远程追踪的分支及其远程追踪记录

提醒对应的开发人员及时清理已经合并到了 origin/master 的远程分支

提醒对应的开发人员及时清理已经远远落后 origin/master 的远程分支

上述操作在 GitLab 下也可以操作一部分,但是…需要人去点,还要有权限才能删除。一个个项目这么点…

git merge 合并分支_git客户端合并分支_git分支合并到主干

清明假期间写了一个脚本,自动清理 1100+ 个分支。

很久没发文,保号发一篇,脚本如下:

#!/bin/bash#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=$1fi# 定义默认检查最深目录层级level=4if [ $2 ];then level=$2fi# 定义过期分支时间参数,默认:非当前年的分支都视为过期分支timeReg=$(date +%Y);if [ $3 ];then timeReg=$3fi
# 定义 log 输出文件log='/tmp/project-branch-alert-log_'$(date +%Y%m%d)'.log'if [ ! -a $log ]; then touch $log echo -e "创建 $logn"ficat /dev/null > $log
# 定义主干远程分支, 一般都为 master,Github 现在为了避嫌改为了 mainmaster='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