解决分支分歧: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 --abortgit rebase --abort中止并返回到之前的状态。这比尝试随机命令直到工作树看起来干净要好。

合并和变基解决的是同一个广泛的问题,但它们讲述的故事不同。合并保留了工作如何汇集在一起。变基创建了更清晰的提交线。在合适的地方使用每一种方法,你的Git历史记录将保持有用,而不是成为风险的来源。