chore: add script to clean local branches that no longer exist on remote
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
# ============================================================
|
||||
# 脚本:git-clean-local-branches.sh
|
||||
# 功能:删除所有远程不存在的本地分支(只保留当前分支及与远程同名的分支)
|
||||
# 用法:./git-clean-local-branches.sh [-n|--dry-run] [-f|--force]
|
||||
# -n, --dry-run 预览要删除的分支,不实际执行
|
||||
# -f, --force 跳过确认提示,直接删除
|
||||
# ============================================================
|
||||
|
||||
set -e
|
||||
|
||||
dry_run=false
|
||||
force=false
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
-n|--dry-run) dry_run=true; shift ;;
|
||||
-f|--force) force=true; shift ;;
|
||||
-h|--help)
|
||||
cat <<EOF
|
||||
用法: $0 [选项]
|
||||
-n, --dry-run 预览要删除的分支,不实际删除
|
||||
-f, --force 跳过删除确认,直接执行
|
||||
-h, --help 显示此帮助
|
||||
EOF
|
||||
exit 0
|
||||
;;
|
||||
*) echo "未知选项: $1"; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# ---------- 刷新远程缓存 ----------
|
||||
echo "==> 刷新所有远程缓存..."
|
||||
git fetch --all --prune --prune-tags 2>/dev/null || git fetch --all --prune
|
||||
for remote in $(git remote); do
|
||||
git remote prune "$remote" 2>/dev/null || true
|
||||
done
|
||||
echo
|
||||
|
||||
# ---------- 获取远程分支完整路径(去掉远程前缀) ----------
|
||||
# 例如 origin/feat/xxx -> feat/xxx
|
||||
remote_branches=$(git branch -r | grep -v '\->' | sed 's/^[^/]*\///' | sort -u)
|
||||
|
||||
# ---------- 收集本地分支(排除当前分支) ----------
|
||||
current_branch=$(git rev-parse --abbrev-ref HEAD)
|
||||
to_delete=()
|
||||
for branch in $(git for-each-ref refs/heads/ --format='%(refname:short)'); do
|
||||
if [[ "$branch" == "$current_branch" ]]; then
|
||||
echo " 保留当前分支: $branch"
|
||||
continue
|
||||
fi
|
||||
if ! echo "$remote_branches" | grep -qxF "$branch"; then
|
||||
to_delete+=("$branch")
|
||||
fi
|
||||
done
|
||||
|
||||
# ---------- 执行删除 ----------
|
||||
if [[ ${#to_delete[@]} -eq 0 ]]; then
|
||||
echo "没有需要删除的分支。"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "以下本地分支在远程不存在,将被删除:"
|
||||
printf " %s\n" "${to_delete[@]}"
|
||||
echo
|
||||
|
||||
if $dry_run; then
|
||||
echo "(试运行,未实际删除)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! $force; then
|
||||
read -p "确认删除以上分支?(y/N) " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo "操作取消。"
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "==> 开始删除..."
|
||||
for branch in "${to_delete[@]}"; do
|
||||
echo "删除: $branch"
|
||||
if ! git branch -d "$branch" 2>/dev/null; then
|
||||
echo " 普通删除失败,尝试强制删除..."
|
||||
git branch -D "$branch" 2>/dev/null || echo " 警告:删除失败,跳过"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "完成。"
|
||||
Reference in New Issue
Block a user