Git 多环境分支管理最佳实践

284 阅读5分钟

Git 多环境分支管理最佳实践

根据你的场景,这是一个典型的 Git Flow 变体工作流。让我为你提供一套完整的解决方案:

工作流概述

feature/add_name → pre_release → master
     ↓               ↓            ↓
   开发分支         预发环境      生产环境

1. 完整的工作流程

阶段1:功能开发

# 1. 从最新的 master 创建功能分支
git checkout master
git pull origin master
git checkout -b feature/add_name

# 2. 开发功能并提交
echo "实现添加姓名功能" > add_name.js
git add add_name.js
git commit -m "feat: implement add name functionality

- Add name input validation
- Add name display component
- Add name storage logic"

# 3. 持续开发中的提交
git add .
git commit -m "feat: add name validation rules"
git commit -m "fix: handle empty name input"
git commit -m "style: improve name display UI"

阶段2:合并到预发环境

# 1. 推送功能分支到远程
git push -u origin feature/add_name

# 2. 切换到 pre_release 分支并更新
git checkout pre_release
git pull origin pre_release

# 3. 合并功能分支到 pre_release(使用 merge 保留完整历史)
git merge feature/add_name --no-ff -m "feat: merge add_name feature to pre_release

- Implemented complete add name functionality
- Ready for pre-release testing"

# 4. 推送到预发环境
git push origin pre_release

阶段3:预发测试和修复

# 如果预发测试发现问题,在功能分支上修复
git checkout feature/add_name

# 修复bug
echo "修复预发测试发现的问题" >> add_name.js
git commit -m "fix: resolve pre-release testing issues

- Fix name validation edge case
- Improve error handling"

# 再次合并到 pre_release
git checkout pre_release
git pull origin pre_release
git merge feature/add_name --no-ff -m "fix: merge bug fixes to pre_release"
git push origin pre_release

阶段4:生产发布

# 1. 预发测试通过后,准备合并到 master
git checkout master
git pull origin master

# 2. 合并到 master(推荐使用 squash merge 保持 master 干净)
git merge feature/add_name --squash
git commit -m "feat: add name functionality

Complete implementation of add name feature including:
- Name input validation and sanitization
- Name display component with proper styling  
- Name storage and retrieval logic
- Comprehensive error handling

Tested in pre-release environment.
Closes #123"

# 3. 推送 master 并打标签
git push origin master
git tag -a v1.2.0 -m "Release v1.2.0: Add name functionality"
git push origin v1.2.0

# 4. 清理功能分支
git branch -d feature/add_name
git push origin --delete feature/add_name

2. 自动化脚本

2.1 合并到预发环境脚本

#!/bin/bash
# merge_to_prerelease.sh

set -e

FEATURE_BRANCH=$1
if [ -z "$FEATURE_BRANCH" ]; then
    echo "Usage: $0 <feature-branch-name>"
    echo "Example: $0 feature/add_name"
    exit 1
fi

echo "🚀 开始合并 $FEATURE_BRANCH 到预发环境"

# 检查当前工作目录是否干净
if [ -n "$(git status --porcelain)" ]; then
    echo "❌ 工作目录不干净,请先提交或暂存更改"
    exit 1
fi

# 推送功能分支
echo "📤 推送功能分支到远程..."
git checkout $FEATURE_BRANCH
git push origin $FEATURE_BRANCH

# 切换到 pre_release 并更新
echo "🔄 更新 pre_release 分支..."
git checkout pre_release
git pull origin pre_release

# 合并功能分支
echo "🔀 合并 $FEATURE_BRANCH 到 pre_release..."
git merge $FEATURE_BRANCH --no-ff -m "feat: merge $FEATURE_BRANCH to pre_release

Ready for pre-release testing and validation.
Includes all commits from feature branch."

# 推送到远程
echo "📤 推送 pre_release 到远程..."
git push origin pre_release

echo "✅ 成功合并 $FEATURE_BRANCH 到预发环境"
echo "🔗 Pre-release URL: https://pre.yourapp.com"
echo "📋 请进行预发测试验证"

2.2 发布到生产环境脚本

#!/bin/bash
# release_to_production.sh

set -e

FEATURE_BRANCH=$1
VERSION=$2

if [ -z "$FEATURE_BRANCH" ] || [ -z "$VERSION" ]; then
    echo "Usage: $0 <feature-branch-name> <version>"
    echo "Example: $0 feature/add_name v1.2.0"
    exit 1
fi

echo "🚀 开始发布 $FEATURE_BRANCH 到生产环境 ($VERSION)"

# 检查工作目录
if [ -n "$(git status --porcelain)" ]; then
    echo "❌ 工作目录不干净,请先提交或暂存更改"
    exit 1
fi

# 更新 master 分支
echo "🔄 更新 master 分支..."
git checkout master
git pull origin master

# 使用 squash merge 合并功能分支
echo "🔀 Squash merge $FEATURE_BRANCH 到 master..."
git merge $FEATURE_BRANCH --squash

# 提示输入提交信息
echo "📝 请输入生产发布的提交信息:"
git commit

# 推送 master
echo "📤 推送 master 到远程..."
git push origin master

# 创建标签
echo "🏷️ 创建版本标签 $VERSION..."
git tag -a $VERSION -m "Release $VERSION"
git push origin $VERSION

# 清理功能分支
echo "🧹 清理功能分支..."
git branch -d $FEATURE_BRANCH
git push origin --delete $FEATURE_BRANCH

echo "✅ 成功发布 $VERSION 到生产环境"
echo "🔗 Production URL: https://yourapp.com"
echo "📊 Monitor: https://monitoring.yourapp.com"

3. 处理复杂场景

3.1 预发环境有其他功能冲突

# 如果 pre_release 有其他人的代码导致冲突
conflict_resolution() {
    echo "🔥 处理预发环境合并冲突"
    
    git checkout pre_release
    git pull origin pre_release
    
    # 尝试合并
    if ! git merge feature/add_name --no-ff; then
        echo "❌ 发现合并冲突,需要手动解决"
        echo "📝 冲突文件:"
        git status --porcelain | grep "^UU"
        
        echo "🛠️ 解决冲突后运行:"
        echo "git add ."
        echo "git commit -m 'resolve: merge conflicts for add_name feature'"
        echo "git push origin pre_release"
        
        return 1
    fi
    
    echo "✅ 合并成功,无冲突"
    git push origin pre_release
}

3.2 紧急修复(Hotfix)

# 生产环境紧急修复流程
hotfix_workflow() {
    HOTFIX_BRANCH="hotfix/urgent-fix"
    
    echo "🚨 开始紧急修复流程"
    
    # 从 master 创建 hotfix 分支
    git checkout master
    git pull origin master
    git checkout -b $HOTFIX_BRANCH
    
    # 修复问题
    echo "修复紧急问题" > hotfix.js
    git add hotfix.js
    git commit -m "hotfix: resolve critical production issue

- Fix security vulnerability in user authentication
- Patch applied to production immediately"
    
    # 合并到 master
    git checkout master
    git merge $HOTFIX_BRANCH --no-ff -m "hotfix: merge urgent fix to master"
    git push origin master
    
    # 打紧急版本标签
    git tag -a v1.1.1 -m "Hotfix v1.1.1: Critical security fix"
    git push origin v1.1.1
    
    # 同步到 pre_release
    git checkout pre_release
    git merge master --no-ff -m "hotfix: sync critical fix to pre_release"
    git push origin pre_release
    
    # 清理 hotfix 分支
    git branch -d $HOTFIX_BRANCH
    git push origin --delete $HOTFIX_BRANCH
    
    echo "✅ 紧急修复完成并同步到所有环境"
}

3.3 功能分支长期开发

# 对于长期开发的功能分支,定期同步 master 的更新
sync_with_master() {
    FEATURE_BRANCH="feature/add_name"
    
    echo "🔄 同步 master 最新更改到功能分支"
    
    # 备份当前工作
    git checkout $FEATURE_BRANCH
    git push origin $FEATURE_BRANCH
    
    # 获取最新 master
    git checkout master
    git pull origin master
    
    # 切回功能分支并 rebase
    git checkout $FEATURE_BRANCH
    
    echo "🔀 选择同步方式:"
    echo "1. Rebase (推荐,保持线性历史)"
    echo "2. Merge (保留分支历史)"
    
    read -p "请选择 (1/2): " choice
    
    case $choice in
        1)
            git rebase master
            echo "✅ Rebase 完成,功能分支已同步最新 master"
            ;;
        2)
            git merge master -m "sync: merge latest master into $FEATURE_BRANCH"
            echo "✅ Merge 完成,功能分支已同步最新 master"
            ;;
        *)
            echo "❌ 无效选择"
            return 1
            ;;
    esac
    
    # 推送更新后的功能分支
    git push origin $FEATURE_BRANCH --force-with-lease
}

4. GitHub/GitLab 集成

4.1 Pull Request 模板

<!-- .github/pull_request_template.md -->
## 功能描述
简要描述此 PR 的功能和变更。

## 变更类型
- [ ] 🆕 新功能 (feature)
- [ ] 🐛 Bug 修复 (fix)
- [ ] 📝 文档更新 (docs)
- [ ] 🎨 代码风格 (style)
- [ ] ♻️ 代码重构 (refactor)
- [ ] ⚡ 性能优化 (perf)
- [ ] ✅ 测试 (test)
- [ ] 🔧 构建/工具 (chore)

## 测试情况
- [ ] 本地测试通过
- [ ] 预发环境测试通过
- [ ] 单元测试通过
- [ ] 集成测试通过

## 检查清单
- [ ] 代码已通过 lint 检查
- [ ] 已添加/更新相关文档
- [ ] 已添加/更新测试用例
- [ ] PR 标题符合约定式提交规范
- [ ] 已在预发环境验证功能

## 相关链接
- 需求文档: 
- 设计稿: 
- 预发环境: https://pre.yourapp.com
- 测试报告: 

## 部署说明
<!-- 如果有特殊部署要求,请在此说明 -->

## 截图/演示
<!-- 如果有 UI 变更,请添加截图或 GIF -->

4.2 分支保护规则

# GitHub CLI 设置分支保护
gh api repos/:owner/:repo/branches/master/protection \
  --method PUT \
  --field required_status_checks='{"strict":true,"contexts":["ci/tests","ci/lint"]}' \
  --field enforce_admins=true \
  --field required_pull_request_reviews='{"required_approving_review_count":2,"dismiss_stale_reviews":true}' \
  --field restrictions=null

5. 工作流自动化

5.1 Git Hooks

# .git/hooks/pre-push
#!/bin/bash
# 推送前检查

protected_branch='master'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')

if [ $current_branch = $protected_branch ]; then
    echo "❌ 直接推送到 $protected_branch 分支被禁止"
    echo "💡 请使用 Pull Request 流程"
    exit 1
fi

echo "✅ 推送检查通过"
exit 0

5.2 GitHub Actions 工作流

# .github/workflows/feature-to-prerelease.yml
name: Feature to Pre-release

on:
  push:
    branches: [ 'feature/**' ]

jobs:
  auto-merge-to-prerelease:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v3
      with:
        fetch-depth: 0
        token: ${{ secrets.GITHUB_TOKEN }}
    
    - name: Setup Git
      run: |
        git config user.name "GitHub Actions"
        git config user.email "actions@github.com"
    
    - name: Merge to pre-release
      run: |
        git checkout pre_release
        git pull origin pre_release
        git merge ${{ github.ref_name }} --no-ff -m "auto: merge ${{ github.ref_name }} to pre_release"
        git push origin pre_release
    
    - name: Comment on PR
      uses: actions/github-script@v6
      with:
        script: |
          github.rest.issues.createComment({
            issue_number: context.issue.number,
            owner: context.repo.owner,
            repo: context.repo.repo,
            body: '🚀 功能已自动合并到预发环境!\n📋 请在预发环境进行测试: https://pre.yourapp.com'
          })

6. 最佳实践总结

🎯 关键原则

  1. 功能分支隔离: 每个功能独立开发,避免相互影响
  2. 预发测试: 在 pre_release 充分测试后才合并到 master
  3. 保持 master 稳定: master 始终是可发布状态
  4. 规范提交信息: 使用约定式提交,便于生成变更日志

📋 工作流检查清单

# 功能开发检查清单
feature_checklist() {
    echo "📋 功能开发检查清单:"
    echo "□ 从最新 master 创建功能分支"
    echo "□ 功能开发完成并自测通过"
    echo "□ 代码通过 lint 和测试"
    echo "□ 提交信息符合规范"
    echo "□ 合并到 pre_release 进行测试"
    echo "□ 预发测试通过"
    echo "□ 创建 Pull Request 到 master"
    echo "□ 代码审查通过"
    echo "□ 合并到 master 并打标签"
    echo "□ 清理功能分支"
}

🚀 一键执行脚本

#!/bin/bash
# deploy_feature.sh - 一键部署功能到各环境

FEATURE_BRANCH=$1
STAGE=$2

case $STAGE in
    "prerelease"|"pre")
        echo "🚀 部署到预发环境"
        ./scripts/merge_to_prerelease.sh $FEATURE_BRANCH
        ;;
    "production"|"prod")
        echo "🚀 部署到生产环境"
        read -p "请输入版本号 (如 v1.2.0): " VERSION
        ./scripts/release_to_production.sh $FEATURE_BRANCH $VERSION
        ;;
    *)
        echo "用法: $0 <feature-branch> <stage>"
        echo "示例: $0 feature/add_name prerelease"
        echo "示例: $0 feature/add_name production"
        exit 1
        ;;
esac

这套工作流能够很好地支持你的多环境开发需求,既保证了代码质量,又提供了足够的灵活性!🎯