Git merge 还是 rebase:关键在于分支是否共享
保留共享历史,或把本地提交重新应用到新的基点。
本文内容
简明答案
Merge 合并历史,可直接快进或创建合并提交。Rebase 在新基点上重新应用提交,因此提交 ID 会改变。改写他人正在使用的分支前,先做好协调。
先理解历史会怎样变化
假设你在 feature 上提交了两次,同时 main 也有新提交。Merge 合并两条开发历史,不会替换已有提交。历史已经分叉时,通常会增加一个合并提交;没有需要合并的分叉时,Git 可以只前移分支指针,也就是 fast-forward。
Rebase 把你的修改重新应用到新基础上。由于父提交发生变化,提交编号也会变化。历史可能更直观,但持有旧提交的同事此时拥有的是另一套历史。应根据分支的共享方式以及仓库规定决定使用哪一种。
准备工作区并更新远程信息
先执行 git status,完成未提交的工作,或者安全地暂存这些工作。再获取远程状态。git fetch origin 更新的是 origin/main,并不会自动移动本地 main。理解这一区别,可以避免误用过时的本地基础进行整合。
下面假设远程名为 origin,工作分支为 feature。整合前创建备份分支,可以保留当前提交的引用。如果备份名字已经存在,应换一个新名字。准备完成后,选择对 origin/main 进行 merge 或 rebase 的相应流程,不要没有目的地连续执行两种操作。
git status
git fetch origin
git switch feature
git branch backup-feature用 merge 保留历史
如果已有提交需要保持不变,merge 通常更合适。完成合并前检查分支和冲突处理结果。
git switch feature
git merge origin/main谨慎处理本地 rebase
Rebase 可以让本地功能分支的历史更线性。解决冲突后检查差异并重新运行相关验证。操作尚未完成时可以取消。
git switch feature
git rebase origin/main解决冲突的含义,而不只是删除标记
冲突可能来自两种不同的业务规则。阅读两边的改动和上下文,仅删除冲突标记不能证明最终行为正确。编辑完成后,用 git add 标记各个已解决文件,并检查暂存的差异。
未完成的 merge 使用 git merge --continue 继续,或 git merge --abort 取消。Rebase 对应 git rebase --continue 和 git rebase --abort。由于 rebase 按提交逐个重放,后续提交可能再次产生冲突。不要只是为了消除报错而使用 --skip,它可能丢弃该提交的改动。
检查结果,并谨慎恢复
整合后,将结果与期望改动比较,并运行仓库规定的检查。如果已经发布的分支经过 rebase,应先与同事协调再更新远程。--force-with-lease 可以防止某些意外的远程状态变化,但不能代替协商,也不会赋予改写历史的权限。
如果整合完成后才发现错误,先查看备份分支和 git reflog。Reflog 记录本地引用移动,可以帮助找到较早状态。考虑 reset 前,先从找到的提交创建恢复分支。还有未提交工作时,不应首先执行 reset --hard。
git reflog --date=iso检查清单
- 先检查未提交的修改。
- 确认谁在使用此分支。
- 冲突解决后审查最终变更。
适用范围
示例假设存在 feature 与 main 分支,请遵循仓库的协作约定。