123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305 |
- #!/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 "$@"
|