90 lines
2.6 KiB
Bash
90 lines
2.6 KiB
Bash
#!/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 "完成。" |