
遇到 divergent branches 提示,说明当前分支和目标分支都有对方没有的提交,Git 无法自动选择默认合并方式(比如 fast-forward),必须由你明确指定策略——这不是 Git 在“卡住”,而是它在等你做决定。
git merge –no-ff 是最安全的默认选择
当执行 git merge main 报出 divergent 提示时,–no-ff 能强制创建一个合并提交,保留两个分支各自的演化路径。这在团队协作中尤其重要:别人能一眼看出这个功能是何时、从哪个分支合入的。
不加 –no-ff 时,Git 可能尝试 fast-forward,但失败后直接中止,不给你任何提示加了之后,即使历史不能快进,也会生成一个清晰的 Merge branch ‘feature/login’ into main 提交如果担心合并后出问题,可以搭配 –no-commit:先应用变更但不自动提交,留出时间检查编译、跑测试
git rebase main 适合个人分支同步,但别用在已推送的分支上
如果你在 feature/login 上工作,而 main 已有新提交,git rebase main 会把你自己的提交“重放”到 main 最新基础上,让历史变成一条直线。这对本地开发很干净,但前提是这个分支还没推送到远程。
已推送到远程的 feature/login 如果被其他人基于它开发,rebase 后强制推送(git push –force-with-lease)会破坏他人本地历史rebase 过程中一旦发生冲突,需要逐个解决并 git add && git rebase –continue,不能跳过rebase 完成后,原提交哈希全部改变,git log 看到的是新哈希,旧记录仍存在但不可达(除非用 git reflog)
git merge –squash 适合把一连串实验性提交压成一个干净变更
当你在功能分支上做了大量调试、改名、补漏等中间提交,又不想让这些过程污染 main 的历史,–squash 就是为此设计的。它不会保留分支结构,只把所有变更打包成一个暂存区状态,由你手动 git commit。
执行后必须手动 git commit,否则什么都不会真正提交合并后该分支与 main 依然 divergent,因为没产生 merge commit,也不更新 feature/login 的 HEAD适合 PR 场景:Reviewer 只需看一个逻辑完整的提交,而不是二十个“修复 typo”“再修一次”
真正容易被忽略的是:divergent 不是错误,只是 Git 拒绝猜你的意图。你选 merge、rebase 还是 squash,本质上是在回答一个问题——你希望这段历史在未来被怎么读、被谁读、用来做什么。选错策略不会丢代码,但可能让下一个人花两小时搞懂你三天前的脑回路。

评论(0)