清理git仓库无用分支

介绍

随着项目经年累月的开发,本地git仓库有很多已开发完成的业务分支,如微博项目每周迭代一个版本,即每周都会产生一个发布分支,这样在本地仓库里,一些早期的分支会干扰我们的分支树,造成看代码极为不便,此脚本即为了解决这个问题,包含以下特点:

  • 会删除当前.git 目录下除当前分支以外的其他分支;
  • 如果有多个需要保留的分支,可修改shell里的whitelist 变量,配置不需要删除的白名单;
  • 如果当前仓库里是多源仓库,即子文件夹里还是单独的git仓库,会遍历一级子文件夹,删除子文件夹里除白名单及当前分支以外的其他分支;
  • 为了代码安全,请在运行此脚本前,检查一下自己未push的本地分支;

代码如下:

#!/bin/bash

# 定义白名单分支
whitelist=("dev" "main" "master" $(git branch --show-current))

# 定义删除分支的函数
clean_branches() {
  local repo_path=$1
  echo "进入仓库: $repo_path"
  cd "$repo_path" || exit  # 进入仓库目录

  # 获取当前分支
  current_branch=$(git branch --show-current)
  echo "当前分支是: $current_branch"

  # 将当前分支加入白名单
  whitelist+=("$current_branch")

  # 获取所有本地分支
  branches=$(git branch | sed 's/*//g' | tr -d ' ')

  # 遍历所有分支并删除不在白名单中的分支
  for branch in $branches; do
    if [[ ! " ${whitelist[@]} " =~ " ${branch} " ]]; then
      echo "删除分支: $branch"
      git branch -D "$branch"
    else
      echo "保留分支: $branch"
    fi
  done

  echo "仓库 $repo_path 分支清理完成"
}

# 获取父仓库的 Git 仓库地址
parent_repo_url=$(git remote get-url origin 2>/dev/null)
# parent_path=$(dirname "$PWD")
parent_path=$(pwd)

# 在当前目录执行分支清理
clean_branches "$(pwd)"

# 遍历当前目录的一级子文件夹
for dir in */ ; do
  cd $parent_path
  if [ -d "${dir%%/}/.git" ]; then
    echo "$dir 是一个 Git 仓库"

    # 进入子文件夹,获取子仓库的 Git 仓库地址
    cd "${dir}" || continue
    child_repo_url=$(git remote get-url origin 2>/dev/null)
    cd ..

    # 检查子仓库地址是否与父仓库不同
    if [ "$child_repo_url" != "$parent_repo_url" ]; then
      echo "${dir} 是独立的 Git 仓库,执行分支清理"
      clean_branches "${dir}"
    else
      echo "${dir} 与父仓库地址相同,跳过"
    fi
  else
    echo "${dir} 不是一个 Git 仓库,跳过"
  fi
done

echo "所有仓库的分支清理完成"