【git】删除本地以及远端已经合并到master的分支

系统

windows

终端

ConEmu

需求

很多本地以及远端存储了已经合并到了master的分支,需要统一清理

清理分支:本地和远端已经合并到master的分支

保护分支:本地和远端的master分支,以master开头,以release-开头的分支,以及 dev test sit uat main 这5个分支,以及以他们开头的

本地和远端的都要清理,需要二次确认

脚本内容

注意上面的操作系统

bash 复制代码
# 清理已合并的远端分支
# 清理已合并分支的函数
# 功能:删除远端和本地已合并到 master 的分支 (排除 release-*)
# 清理已合并分支的函数
# 修复了 grep 参数报错问题,优化了分支过滤逻辑

clean-merged-branches() {
    echo "🚀 开始检查已合并到 master 的分支..."

    # 1. 确保获取了最新的远端信息
    echo ""
    echo "📡 同步远端仓库信息..."
    git fetch --prune --all
    git checkout master 2>/dev/null || echo "已在 master 分支"
    git pull origin master

    # ==========================================
    # 第一步:处理远端分支
    # ==========================================
    echo ""
    echo "🔍 正在查找远端已合并的分支..."

    local remote_to_delete=()
    local remote_to_skip=()

    # 逐行读取远端已合并的分支
    while IFS= read -r line; do
        # 去除开头的空格
        line=$(echo "$line" | sed 's/^[ ]*//')
        
        # 跳过包含 -> 的行(HEAD 指向)
        if [[ "$line" == *"->"* ]]; then
            continue
        fi
        
        # 去除 'origin/' 前缀
        branch="${line#origin/}"
        
        # 跳过空行
        if [[ -z "$branch" ]]; then
            continue
        fi
        
        # --- 核心过滤逻辑 ---
        # 排除 master、master-*、release-*、test、test-*、uat、uat-*、main、main-*、sit、sit-*、dev、dev-* 开头的分支
        if [[ "$branch" == "master" ]]; then
            remote_to_skip+=("$branch (主分支)")
        elif [[ "$branch" =~ ^master- ]]; then
            remote_to_skip+=("$branch (master前缀分支)")
        elif [[ "$branch" =~ ^release- ]]; then
            remote_to_skip+=("$branch (release分支)")
        elif [[ "$branch" =~ ^test ]]; then
            remote_to_skip+=("$branch (test分支)")
        elif [[ "$branch" =~ ^uat ]]; then
            remote_to_skip+=("$branch (uat分支)")
        elif [[ "$branch" =~ ^main ]]; then
            remote_to_skip+=("$branch (main分支)")
        elif [[ "$branch" =~ ^sit ]]; then
            remote_to_skip+=("$branch (sit分支)")
        elif [[ "$branch" =~ ^dev ]]; then
            remote_to_skip+=("$branch (dev分支)")
        else
            remote_to_delete+=("$branch")
        fi
    done < <(git branch -r --merged origin/master)

    # 显示被跳过的分支(调试用,可选)
    if [ ${#remote_to_skip[@]} -gt 0 ]; then
        echo ""
        echo "⏭️ 以下分支被自动跳过(受保护):"
        for br in "${remote_to_skip[@]}"; do
            echo "   - $br"
        done
    fi

    if [ ${#remote_to_delete[@]} -eq 0 ]; then
        echo ""
        echo "✅ 没有发现需要清理的远端分支。"
    else
        echo ""
        echo "📋 发现以下远端分支已合并到 master:"
        for br in "${remote_to_delete[@]}"; do
            echo "   - origin/$br"
        done

        echo ""
        read -p "⚠️ 确认删除上述远端分支吗?(y/N): " confirm
        if [[ "$confirm" =~ ^[Yy]$ ]]; then
            if [ ${#remote_to_delete[@]} -gt 0 ]; then
                git push origin --delete "${remote_to_delete[@]}"
                echo "✅ 远端分支删除完成。"
            fi
        else
            echo "❌ 取消删除远端分支。"
        fi
    fi

    # ==========================================
    # 第二步:处理本地分支
    # ==========================================
    echo ""
    echo "🔍 正在查找本地已合并的分支..."

    local local_to_delete=()
    local local_to_skip=()

    # 逐行读取本地已合并的分支
    while IFS= read -r line; do
        # 去除开头的空格和 * 标记
        branch=$(echo "$line" | sed 's/^[* ]*//')
        
        # 跳过空行
        if [[ -z "$branch" ]]; then
            continue
        fi
        
        # --- 核心过滤逻辑 ---
        # 排除 master、master-*、release-*、test、test-*、uat、uat-*、main、main-*、sit、sit-*、dev、dev-* 开头的分支
        if [[ "$branch" == "master" ]]; then
            local_to_skip+=("$branch (主分支)")
        elif [[ "$branch" =~ ^master- ]]; then
            local_to_skip+=("$branch (master前缀分支)")
        elif [[ "$branch" =~ ^release- ]]; then
            local_to_skip+=("$branch (release分支)")
        elif [[ "$branch" =~ ^test ]]; then
            local_to_skip+=("$branch (test分支)")
        elif [[ "$branch" =~ ^uat ]]; then
            local_to_skip+=("$branch (uat分支)")
        elif [[ "$branch" =~ ^main ]]; then
            local_to_skip+=("$branch (main分支)")
        elif [[ "$branch" =~ ^sit ]]; then
            local_to_skip+=("$branch (sit分支)")
        elif [[ "$branch" =~ ^dev ]]; then
            local_to_skip+=("$branch (dev分支)")
        else
            local_to_delete+=("$branch")
        fi
    done < <(git branch --merged master)

    # 显示被跳过的分支(调试用,可选)
    if [ ${#local_to_skip[@]} -gt 0 ]; then
        echo ""
        echo "⏭️ 以下本地分支被自动跳过(受保护):"
        for br in "${local_to_skip[@]}"; do
            echo "   - $br"
        done
    fi

    if [ ${#local_to_delete[@]} -eq 0 ]; then
        echo ""
        echo "✅ 没有发现需要清理的本地分支。"
    else
        echo ""
        echo "📋 发现以下本地分支已合并到 master:"
        for br in "${local_to_delete[@]}"; do
            echo "   - $br"
        done

        echo ""
        read -p "⚠️ 确认删除上述本地分支吗?(y/N): " confirm_local
        if [[ "$confirm_local" =~ ^[Yy]$ ]]; then
            if [ ${#local_to_delete[@]} -gt 0 ]; then
                git branch -d "${local_to_delete[@]}"
                echo "✅ 本地分支删除完成。"
            fi
        else
            echo "❌ 取消删除本地分支。"
        fi
    fi

    echo ""
    echo "🎉 清理任务结束。"
}

直接把这个内容放到 ~/.bashrc文件里面,windows打开方式

bash 复制代码
notepad ~/.bashrc 

然后

bash 复制代码
source ~/bashrc

然后重启 conemu,找到你的git仓库执行

bash 复制代码
clean-merged-branches
相关推荐
养肥胖虎3 小时前
Git提交规范笔记:feat和fix到底该怎么写
git·conventionalcommits
手握风云-4 小时前
深入 Git:它是如何记录世界的(二)
git
jkyy20145 小时前
深耕AI健康医疗数据智库,赋能企业构建主动健康管理新生态
大数据·人工智能·健康医疗
2601_961946087 小时前
AI API 网关实战:从单 Key 管理到企业级多租户架构
大数据·人工智能·金融·架构·api·个人开发
大大大大晴天9 小时前
Flink CDC 深度解析:从原理到实践的全链路指南
大数据·flink
IT新视界9 小时前
Elasticsearch信创国产化替代
大数据·elasticsearch·搜索引擎
汇策研习社10 小时前
改良版ADX指标实战指南:告别传统ADX滞后、震荡误判难题
大数据·经验分享·金融·区块链·fastbull
SelectDB10 小时前
宽表元数据膨胀怎么解?Doris Segment V3 对比 Parquet、Lance
大数据·数据库·数据分析
隔窗听雨眠11 小时前
从追赶者到定义者:中国BI如何借助AI实现弯道超车
大数据·人工智能
cspttty11 小时前
二本软件工程专业好就业吗?毕业后能做哪些岗位
大数据·软件工程