应使用 git merge --no-commit --no-ff 批量合并指定分支,先验证分支存在性,拦截 protected 分支(如 main、release/*),遇冲突立即退出并提示,禁止用 rebase,合并后不自动 push,清理需人工确认。

怎么安全地批量合并指定分支到当前分支
直接用 git merge 循环跑容易出错——比如某个分支不存在、有冲突没处理、或者误把 feature 分支合进 main。必须先验证分支存在性,再加 --no-commit --no-ff 控制行为。
- 先用
git show-ref --heads或git branch --format='%(refname:short)'获取本地所有分支名,过滤出目标模式(如feature/开头) - 对每个候选分支执行
git merge --no-commit --no-ff <branch>,不自动提交,便于人工检查冲突或暂存状态 - 合并后立刻运行
git status --porcelain判断是否干净:输出为空表示成功,否则需中断流程并报错 - 避免用
git checkout切换主干——脚本应在目标基线分支上运行(例如已在main),只做“合入”动作
如何防止合并时覆盖他人提交或跳过保护分支
Git 默认不会阻止你往 main 合并,但生产环境往往禁止直接 push。脚本里得主动拦截高风险目标。
- 硬编码黑名单:检查待合分支名是否匹配
main、release/*、hotfix/*等,匹配则echo "SKIP: $branch protected"; continue - 读取
.git/config或远程仓库的protected branches配置不现实,Shell 无法可靠解析 GitHub/GitLab API,不如靠本地规则约束 - 如果依赖 CI 检查(如 require PRs),合并后不要
git push——留给人手动触发 PR 或等 CI 通过后再推
遇到冲突时怎么让脚本停下来而不是强行继续
git merge 出现冲突时返回非零退出码,但默认不终止循环。必须显式判断并退出,否则后续分支会反复尝试在已冲突工作区操作,导致混乱。
- 每次
git merge --no-commit --no-ff $branch后紧跟if [ $? -ne 0 ]; then echo "CONFLICT on $branch"; exit 1; fi - 不要用
|| true吞掉错误,也不要设set -e——它会在git status返回 1(有未提交变更)时误杀脚本 - 冲突发生后,工作区处于合并中状态,此时
git merge --abort可恢复,但建议由人工决定是否中止整个批次
为什么不用 git rebase 替代 merge
rebase 会改写提交历史,在多人协作分支上极其危险。批量操作更不能碰。
-
git rebase要求目标分支是快进可达的,而实际中feature/A和feature/B可能互不包含对方提交,强制 rebase 会导致重复提交或丢失 commit - rebase 过程中若某一分支失败,其他分支的变基状态无法原子回滚,
git reflog也难追溯原始顺序 - 除非明确要求线性历史且所有分支都基于同一旧基线(如 daily build 场景),否则一律用
merge+--no-ff保留拓扑信息
真正麻烦的是合并后清理:脚本没法自动判断哪些分支已合入、是否可删。这部分得靠人看 git log --oneline --graph 或查 git merge-base 结果,别指望 Shell 自动搞定。


















