【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
相关推荐
果然_1 天前
为什么你的 PR 总是多出一堆奇怪的 commit?90% 的人都踩过这个 Git 坑
前端·git
yyuuuzz1 天前
独立站搭建:从入门到避坑实战
前端·git·github
splage1 天前
Nginx 反向代理之upstream模块以及完整配置反向代理示例
git·nginx·github
福老板的生意经1 天前
从成本失控到ROI翻倍:企业数字化营销投放的落地路径与工具选型指南
大数据·运维·人工智能
@insist1231 天前
网络工程师-实战配置篇(二):精通 ACL 与策略路由,实现智能流量管控
大数据·网络·网络工程师·软考·软件水平考试
互联网科技看点1 天前
以青春种黄芪 用科技兴乡村
大数据·人工智能·科技
阿崽meitoufa1 天前
hermes-agent安装到本地 Git方法
git·hermes·hermes-agent
2501_933670791 天前
2026大学生必看!互联网行业含金量最高
大数据
Ulyanov1 天前
像素迷宫:路径规划算法的可视化与实战
大数据·开发语言·python·算法
pride.li1 天前
Git 笔记:将一段旧历史压缩成一个提交
大数据·elasticsearch·搜索引擎