#!/usr/bin/env node const { execSync } = require('child_process'); const COLORS = { red: '\x1b[31m', green: '\x1b[32m', yellow: '\x1b[33m', cyan: '\x1b[36m', reset: '\x1b[0m' }; function log(message, color = 'reset') { console.log(`${COLORS[color]}${message}${COLORS.reset}`); } function exec(command, options = {}) { try { return execSync(command, { encoding: 'utf-8', stdio: options.silent ? 'pipe' : 'inherit', ...options }); } catch (error) { if (options.ignoreError) { return error.stdout || ''; } throw error; } } function run() { log('\n========================================', 'cyan'); log(' 合并 master 到 production 分支', 'cyan'); log('========================================\n', 'cyan'); // 1. 检查是否有未提交的更改 log('>>> 检查工作区状态...', 'yellow'); const status = exec('git status --porcelain', { silent: true }); if (status.trim()) { log('\n错误: 工作区有未提交的更改,请先提交或暂存', 'red'); log('运行 git status 查看详情\n', 'red'); process.exit(1); } log('工作区干净\n', 'green'); // 2. 获取当前分支名 const currentBranch = exec('git branch --show-current', { silent: true }).trim(); log(`当前分支: ${currentBranch}\n`, 'cyan'); // 3. 拉取最新代码 log('>>> 拉取远程最新代码...', 'yellow'); try { exec('git fetch origin'); } catch (error) { log('\n错误: 拉取远程代码失败', 'red'); process.exit(1); } log('拉取完成\n', 'green'); // 4. 切换到 master 并更新 log('>>> 切换到 master 分支并更新...', 'yellow'); try { exec('git checkout master'); exec('git pull origin master'); } catch (error) { log('\n错误: 更新 master 分支失败', 'red'); process.exit(1); } log('master 分支已更新\n', 'green'); // 5. 切换到 production 并更新 log('>>> 切换到 production 分支并更新...', 'yellow'); try { exec('git checkout production'); exec('git pull origin production'); } catch (error) { log('\n错误: 更新 production 分支失败,分支可能不存在', 'red'); log('请先创建 production 分支: git checkout -b production\n', 'yellow'); exec(`git checkout ${currentBranch}`, { ignoreError: true }); process.exit(1); } log('production 分支已更新\n', 'green'); // 6. 合并 master 到 production log('>>> 合并 master 到 production...', 'yellow'); try { exec('git merge master --no-edit'); } catch (error) { log('\n错误: 合并过程中发生冲突!', 'red'); log('请手动解决冲突后再提交', 'red'); log('\n冲突文件:', 'yellow'); exec('git diff --name-only --diff-filter=U', { ignoreError: true }); log('\n解决冲突后运行:', 'yellow'); log(' git add .', 'cyan'); log(' git commit', 'cyan'); log(' git push origin production\n', 'cyan'); log('或放弃合并:', 'yellow'); log(' git merge --abort\n', 'cyan'); process.exit(1); } log('合并成功\n', 'green'); // 7. 推送到远程 log('>>> 推送到远程 production 分支...', 'yellow'); try { exec('git push origin production'); } catch (error) { log('\n错误: 推送失败', 'red'); process.exit(1); } log('推送成功\n', 'green'); // 8. 切换回原分支 log(`>>> 切换回原分支 ${currentBranch}...`, 'yellow'); exec(`git checkout ${currentBranch}`, { ignoreError: true }); log('\n========================================', 'green'); log(' master 已成功合并到 production!', 'green'); log('========================================\n', 'green'); } run();