#!/usr/bin/env bash # 分支管理自动化脚本 # 实现智能分支检查、清理和流程指导 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 获取仓库根目录 get_repo_root() { if git rev-parse --show-toplevel >/dev/null 2>&1; then git rev-parse --show-toplevel else echo "Error: 不是Git仓库或未初始化Git" >&2 exit 1 fi } # 分析分支状态 analyze_branches() { local repo_root="$1" local current_branch=$(git branch --show-current) local main_branch="main" echo -e "${BLUE}📊 分支状态分析${NC}" echo "====================================" # 列出所有功能分支 local feature_branches=() while IFS= read -r branch; do branch=$(echo "$branch" | sed 's/^[* ] //') if [[ "$branch" =~ ^[0-9]{3}- ]] && [[ "$branch" != "$main_branch" ]]; then feature_branches+=("$branch") fi done < <(git branch) if [ ${#feature_branches[@]} -eq 0 ]; then echo -e "${GREEN}✅ 无功能分支,分支状态干净${NC}" return 0 fi echo -e "${YELLOW}📋 发现 ${#feature_branches[@]} 个功能分支:${NC}" for branch in "${feature_branches[@]}"; do local spec_dir="$repo_root/specs/$branch" local has_spec_dir="" local has_implementation="" local commits_ahead="" # 检查是否有specs目录 if [ -d "$spec_dir" ]; then has_spec_dir="✅" else has_spec_dir="❌" fi # 检查是否有实现代码(src目录中的变更) local changed_files=$(git diff --name-only "$main_branch..$branch" 2>/dev/null | grep "^src/" | wc -l || echo "0") if [ "$changed_files" -gt 0 ]; then has_implementation="✅ ($changed_files files)" else has_implementation="❌" fi # 检查相对main的提交数 commits_ahead=$(git rev-list --count "$main_branch..$branch" 2>/dev/null || echo "0") # 输出分支状态 printf " %-25s | Spec: %s | Code: %-12s | Commits: %s\n" \ "$branch" "$has_spec_dir" "$has_implementation" "$commits_ahead" done echo "" return ${#feature_branches[@]} } # 建议操作 suggest_actions() { local branch_count=$1 local current_branch=$(git branch --show-current) echo -e "${BLUE}💡 建议操作${NC}" echo "====================================" if [ "$branch_count" -eq 0 ]; then echo -e "${GREEN}✨ 可以安全创建新功能分支${NC}" return 0 fi if [ "$branch_count" -eq 1 ] && [[ "$current_branch" =~ ^[0-9]{3}- ]]; then echo -e "${YELLOW}🎯 专注完成当前分支: $current_branch${NC}" echo "建议: 完成后运行 'manage-branches.sh --merge' 合并到main" elif [ "$branch_count" -ge 2 ]; then echo -e "${RED}⚠️ 发现多个功能分支,建议清理${NC}" echo "选项1: 删除重复或不需要的分支" echo "选项2: 完成并合并已完成的分支" echo "选项3: 运行 'manage-branches.sh --cleanup' 进行交互式清理" fi } # 交互式分支清理 interactive_cleanup() { local repo_root="$1" local current_branch=$(git branch --show-current) local main_branch="main" echo -e "${BLUE}🧹 交互式分支清理${NC}" echo "====================================" # 获取所有功能分支 local feature_branches=() while IFS= read -r branch; do branch=$(echo "$branch" | sed 's/^[* ] //') if [[ "$branch" =~ ^[0-9]{3}- ]] && [[ "$branch" != "$main_branch" ]]; then feature_branches+=("$branch") fi done < <(git branch) if [ ${#feature_branches[@]} -eq 0 ]; then echo -e "${GREEN}✅ 没有需要清理的功能分支${NC}" return 0 fi for branch in "${feature_branches[@]}"; do echo "" echo -e "${YELLOW}📝 分支: $branch${NC}" # 显示分支信息 local commits=$(git rev-list --count "$main_branch..$branch" 2>/dev/null || echo "0") local spec_dir="$repo_root/specs/$branch" echo " 提交数: $commits" if [ -d "$spec_dir" ]; then echo " 规范目录: ✅ $spec_dir" else echo " 规范目录: ❌ 不存在" fi # 询问操作 echo "" echo "选择操作:" echo " 1) 保留分支" echo " 2) 删除分支 (谨慎!)" echo " 3) 合并到main并删除" echo " 4) 跳过" read -p "请选择 (1-4): " choice case $choice in 1) echo -e "${GREEN}✅ 保留分支 $branch${NC}" ;; 2) echo -e "${RED}⚠️ 确认删除分支 $branch? 这将丢失所有变更!${NC}" read -p "输入 'DELETE' 确认: " confirm if [ "$confirm" = "DELETE" ]; then git branch -D "$branch" rm -rf "$spec_dir" echo -e "${RED}🗑️ 已删除分支 $branch${NC}" else echo -e "${YELLOW}❌ 取消删除${NC}" fi ;; 3) echo -e "${BLUE}🔄 合并分支 $branch 到 main${NC}" # 检查是否有未提交的变更 if ! git diff-index --quiet HEAD --; then echo -e "${YELLOW}⚠️ 当前分支有未提交的变更,请先提交${NC}" continue fi # 切换到main并合并 git checkout main git merge "$branch" git branch -d "$branch" echo -e "${GREEN}✅ 已合并并删除分支 $branch${NC}" ;; 4) echo -e "${BLUE}⏭️ 跳过分支 $branch${NC}" ;; *) echo -e "${RED}❌ 无效选择,跳过${NC}" ;; esac done } # 自动合并当前分支 auto_merge_current() { local current_branch=$(git branch --show-current) local main_branch="main" if [[ ! "$current_branch" =~ ^[0-9]{3}- ]]; then echo -e "${RED}❌ 当前不在功能分支上${NC}" exit 1 fi echo -e "${BLUE}🔄 自动合并当前分支: $current_branch${NC}" # 检查是否有未提交的变更 if ! git diff-index --quiet HEAD --; then echo -e "${YELLOW}⚠️ 发现未提交的变更,正在提交...${NC}" git add . git commit -m "完成功能实现 - 自动提交" fi # 切换到main并合并 git checkout main git merge "$current_branch" --no-ff -m "合并功能分支: $current_branch" git branch -d "$current_branch" echo -e "${GREEN}✅ 已成功合并并删除分支: $current_branch${NC}" } # 检查新功能创建前的状态 pre_create_check() { echo -e "${BLUE}🔍 新功能创建前检查${NC}" echo "====================================" local branch_count analyze_branches "$(get_repo_root)" branch_count=$? if [ "$branch_count" -eq 0 ]; then echo -e "${GREEN}✅ 可以安全创建新功能分支${NC}" return 0 elif [ "$branch_count" -eq 1 ]; then local current_branch=$(git branch --show-current) if [[ "$current_branch" =~ ^[0-9]{3}- ]]; then echo -e "${YELLOW}⚠️ 建议先完成当前分支: $current_branch${NC}" echo "运行 'manage-branches.sh --merge' 来合并当前分支" else echo -e "${YELLOW}⚠️ 发现1个功能分支,建议清理后再创建新功能${NC}" fi return 1 else echo -e "${RED}🚫 发现多个功能分支,强烈建议先清理${NC}" echo "运行 'manage-branches.sh --cleanup' 进行清理" return 2 fi } # 显示帮助信息 show_help() { echo "分支管理自动化工具" echo "" echo "用法: $0 [选项]" echo "" echo "选项:" echo " --status 显示分支状态分析" echo " --cleanup 交互式分支清理" echo " --merge 自动合并当前功能分支到main" echo " --check 新功能创建前检查" echo " --help 显示帮助信息" echo "" echo "示例:" echo " $0 --status # 查看当前分支状态" echo " $0 --check # 检查是否适合创建新功能" echo " $0 --cleanup # 交互式清理分支" echo " $0 --merge # 合并当前分支到main" } # 主函数 main() { local repo_root repo_root=$(get_repo_root) cd "$repo_root" case "${1:-}" in --status) analyze_branches "$repo_root" suggest_actions $? ;; --cleanup) interactive_cleanup "$repo_root" ;; --merge) auto_merge_current ;; --check) pre_create_check ;; --help|-h) show_help ;; "") # 默认行为:显示状态和建议 analyze_branches "$repo_root" suggest_actions $? ;; *) echo -e "${RED}❌ 未知选项: $1${NC}" >&2 show_help exit 1 ;; esac } main "$@"