解决分支分歧:Git合并与变基策略
比较git merge和git rebase在分歧分支、冲突处理、共享历史以及选择团队安全工作流方面的差异。
解决分支分歧:Git合并与变基策略
Git的合并和变基都能在分支与另一分支出现分歧时提供帮助。它们的区别在于如何保留历史记录,选择错误的方法可能会让协作变得比实际需要更困难。
你不需要为每次更改都追求完美的历史记录。但你需要一个团队理解且能保持共享分支稳定的策略。
分歧历史意味着什么
当两个分支在共同起点之后有不同的提交时,就会产生分歧历史。例如,你在周一从main分支创建了feature/log-cleanup分支。周二,有人将一个安全修复合并到了main分支。现在你的分支和main分支各自拥有对方没有的提交。
你可以通过以下命令查看:
git log --oneline --graph --decorate --all
你也可能会看到Git提示你的分支与远程分支出现了分歧。这意味着双方都有独特的提交。Git需要你决定如何合并它们。
两种常用工具是合并和变基:
git merge main
或:
git rebase main
两者都能产生相同的最终文件内容,但历史记录会有所不同。
Git合并的工作原理
合并会整合历史记录,而不会重写现有提交。如果你的分支和main分支都向前推进了,Git会创建一个合并提交,将两条工作线连接起来。
典型的流程如下:
git switch feature/log-cleanup
git fetch origin
git merge origin/main
如果没有冲突,Git会创建一个合并提交,或者在可能的情况下进行快进合并。如果有冲突,Git会暂停并请你解决冲突。
当你希望保留协作的真实形态时,合并是很好的选择。它展示了工作是并行进行的,后来才被合并。这对于长期运行的分支、发布分支和共享功能分支非常有用。
缺点是频繁的合并可能会增加噪音。一个包含许多“将main合并到feature”提交的分支可能更难浏览。这并不意味着它错了,但可能会使历史记录不够整洁。
在以下情况下使用合并:
- 分支是与其他开发者共享的。
- 你希望避免重写提交历史。
- 你的团队重视集成点的精确记录。
- 你正在更新发布分支或受保护分支。
对于已经推送并被他人使用的分支,合并通常是更安全的默认选择。
Git变基的工作原理
变基会将你的分支提交移动到新的基础提交之上。它不会显示两条分歧的线通过合并提交连接,而是使分支历史变成线性的。
典型的流程如下:
git switch feature/log-cleanup
git fetch origin
git rebase origin/main
Git会逐个重放你的提交到最新的main分支之上。如果出现冲突,Git会在无法重放的提交处停止。解决冲突后,继续执行:
git add <fixed-files>
git rebase --continue
如果变基变得混乱,你可以退出:
git rebase --abort
变基对于本地私有分支非常有用,因为它使历史记录易于阅读。审查者可以看到你的提交,就像它们从一开始就建立在最新的main分支上一样。
在以下情况下使用变基:
- 分支是你自己的且未共享。
- 你希望拥有干净、线性的提交历史。
- 你正在准备一个分支,以便在打开拉取请求之前。
- 你的团队明确偏好变基后的功能分支。
主要规则很简单:除非你的团队期望如此,否则不要变基公共提交。变基会重写提交哈希值。如果其他人基于你的旧提交进行了工作,你的重写可能会给他们带来混乱。
有关更多日常Git历史工具,请参阅探索项目历史。
在合并或变基期间处理冲突
当Git无法自动合并更改时,就会发生冲突。这在繁忙的文件中很常见,例如部署清单、依赖锁定文件和共享配置文件。
首先检查状态:
git status
打开冲突文件并查找冲突标记:
<<<<<<< HEAD
当前分支版本
=======
传入版本
>>>>>>> branch-name
你的任务是用你实际想要的最终内容替换标记块。不要保留标记。
编辑后,暂存文件:
git add path/to/file
对于合并,最后执行:
git commit
对于变基,继续执行:
git rebase --continue
解决冲突后运行测试或至少相关的验证命令。一个文件可能在语法上是干净的,但在逻辑上是错误的。例如,两个Kubernetes YAML更改可能在没有冲突的情况下合并,但仍然定义了重复的端口或不匹配的标签。
选择团队策略
最好的策略是为你的项目创建可预测历史的策略。许多团队对私有功能分支使用变基,对拉取请求使用合并提交。其他人将所有功能工作压缩为一个提交。一些基础设施团队更喜欢合并提交,因为它们可以准确显示分支何时被集成。
选择一个规则并记录下来。一个简单的策略可能是:
- 在审查之前变基你自己的功能分支。
- 永远不要变基
main、发布分支或共享分支。 - 对已批准的拉取请求使用合并提交。
- 对小型、单一目的的修复使用压缩合并。
这可以防止在紧急工作时发生Git风格争论。它也使自动化更容易,因为CI、发布说明和部署工具可以依赖一致的历史记录。
何时寻求帮助
在对可能被他人使用的分支进行变基后强制推送之前,请先询问。当冲突涉及安全设置、数据库迁移、生产部署文件或你不理解的生成锁定文件时,也请询问。
如果合并或变基变得混乱,请停止并使用git status检查状态。你通常可以使用git merge --abort或git rebase --abort中止并返回到之前的状态。这比尝试随机命令直到工作树看起来干净要好。
合并和变基解决的是同一个广泛的问题,但它们讲述的故事不同。合并保留了工作如何汇集在一起。变基创建了更清晰的提交线。在合适的地方使用每一种方法,你的Git历史记录将保持有用,而不是成为风险的来源。