Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019 | TFS 2018

Visual Studio 2019 | Visual Studio 2022

合并或变基 时,你是在告知 Git 将一个分支上所做的更改与另一个分支上所做的更改相集成。 通常,Git 会在没有你的帮助的情况下自动完成合并或变基。 但是,如果 Git 发现在一个分支上所做的更改与另一个分支上所做的更改冲突,则会提示你解决冲突。 当合并的分支以不同的方式编辑同一文件行时,或者当一个分支修改文件而另一个分支删除该文件时,可能会发生合并冲突。 解决合并冲突的过程适用于 Git 合并和变基。

可以在 Visual Studio 中解决合并冲突,也可以使用命令行和任何文本编辑器来解决合并冲突。

有关 Git 工作流的概述,请参阅 Azure Repos Git 教程

本文提供了下列任务的过程:

  • 了解合并冲突
  • 解决合并冲突
  • 了解合并冲突

    Git 合并或变基将源分支中的提交集成到当前本地分支(目标分支)中。 Git 合并 执行一个 快进 非快进 合并。 非快进合并也称为三向合并或 true 合并。 Git 变基 是另一种合并类型。 下图显示了这些合并类型。

    对于 Git 合并,如果目标分支的尖端存在于源分支中,则默认合并类型将为快进合并。 否则,默认合并类型将为非快进合并。

    快进 合并永远不会有合并冲突,因为如果目标分支的尖端已经从源分支偏离,Git 就不会应用快进合并。 默认情况下,Git 尽可能使用快进合并。 例如,Git 将对本地分支(你仅通过从它的远程对应分支拉取来更新它)应用快进合并。

    非快进 合并会生成一个新的目标分支“合并提交”,将源分支更改与目标分支更改集成。 适用的更改是在最后一次提交(对两个分支通用)之后进行的更改。 在上图中,提交 C 是两个分支中的最后一个通用提交。 如果任何源分支更改与任何目标分支更改冲突,则 Git 将提示你解决合并冲突。 合并提交 (L) 包含集成的源分支和目标分支更改。 源分支尖端和目标分支尖端(K 和 E)是合并提交的父级。 在分支的 提交历史记录 中,合并提交是有用的合并操作标记,并清楚地显示合并的分支。

    Git 变基 对目标分支的提交历史记录进行重新排序,使其包含所有源分支提交,后跟自上次通用提交以来的所有目标分支提交。 在上图中,提交 C 是两个分支中的最后一个通用提交。 另一种查看方法是,变基在源分支历史记录的基础上重播目标分支中的更改。 如果任何源分支更改与任何目标分支更改冲突,则 Git 将提示你解决合并冲突。 与快进合并一样,变基不会创建合并提交。 值得注意的是,变基会更改现有目标分支提交的顺序,而其他合并策略的情况并非如此。 在上图中,提交 K' 包含与 K 相同的更改,但具有新的提交 ID,因为它链接回提交 E 而不是 C。

    Git 合并和变基仅修改目标分支,源分支保持不变。 遇到一个或多个合并冲突时,必须解决这些冲突才能完成合并或变基。 或者,可以取消合并/变基操作,并将目标分支返回到其以前的状态。

    有关合并选项和策略的详细信息,请参阅 Git 参考手册 Git 合并策略

    何时解决合并冲突

    Git 合并 和 Git 变基 广泛用于 Git 工作流 中。 处理本地功能或 bug 修复分支时,常见做法是:

  • 通过定期 拉取 以提取和合并远程提交,使本地 main 分支与其远程对应分支保持同步。
  • 使用重基或合并,将本地 main 分支更新集成到本地功能分支。
  • 通过将本地功能分支 推送 到相应的远程分支来备份你在本地功能分支上的工作。
  • 功能完成后,创建 拉取请求 以将远程功能分支合并到远程 main 分支中。
  • 通过经常将远程更改集成到本地存储库中,可以随时了解其他人最近的工作,并及时解决出现的任何合并冲突。

    解决合并冲突

    解决合并冲突的过程适用于 Git 合并和 Git 变基。 虽然以下步骤介绍了如何在合并期间解决合并冲突,但你也可以类似地在变基过程中解决合并冲突。

    如果源分支是 远程跟踪 分支,请在合并之前运行 Git 提取 ,确保该分支是最新的。 或者,运行 Git pull 命令,该命令将 Git 提取与 Git 合并相结合。

    Visual Studio 2022 通过使用“Git”菜单、“Git 更改”和“解决方案资源管理器”中的上下文菜单提供 Git 版本控制体验。 Visual Studio 2019 版本 16.8 还提供了团队资源管理器 Git 用户界面。 有关详细信息,请参阅“Visual Studio 2019 - 团队资源管理器”选项卡。

  • 在“Git 存储库”窗口的“分支”窗格中,签出目标分支。 然后,右键单击源分支,并选择“将 <source-branch> 合并到 <target-branch>”。

  • 如果 Git 因冲突而停止了合并,Visual Studio 将通知你。 在这种情况下,可以解决冲突,也可以取消合并,返回到合并前状态。 “Git 更改”窗口的“未合并的更改”部分列出了存在合并冲突的文件。 对于内容中存在合并冲突的文件,双击该文件以在合并编辑器中将其打开。

  • 在合并编辑器中,“传入”窗格显示源分支文件版本,“当前”窗格显示目标分支文件版本,“结果”窗格显示生成的合并文件。 若要应用特定的源或目标分支更改,请选中要保留的冲突行旁边的复选框。 还可以直接在“结果”窗格中编辑合并文件。 解决当前文件中的所有合并冲突后,选择“接受合并”。 对存在内容冲突的每个文件重复此步骤。

  • 对于在一个分支中编辑并在另一个分支中删除的文件,请右键单击该文件,选择所需的分支操作。

  • 在“Git 更改”窗口中,输入一个提交消息并选择“提交已暂存内容”,以便在解决所有文件的所有合并冲突后完成合并。

    Visual Studio 2019 版本 16.8 及更高版本提供 Git 版本控制体验,同时保留团队资源管理器 Git 用户界面。 要使用团队资源管理器,请从菜单栏中取消选中“工具”>“选项”>“预览功能”>“新 Git 用户体验”。 可以互换使用任一界面中的 Git 功能。

  • 在团队资源管理器的“分支”视图中,签出目标分支。 然后,右键单击源分支,选择“合并自”。

  • 验证合并选项,然后单击“合并”。

  • 如果 Git 因冲突而停止了合并,Visual Studio 将通知你。 在这种情况下,可以解决冲突,也可以取消合并,返回到合并前状态。 若要解决冲突,请选择“冲突”以打开“解决冲突”视图。

  • “解决冲突”视图列出了存在合并冲突的文件。 从列表中选择一个文件以查看该文件的解决选项。

  • 对于内容中存在合并冲突的文件,选择“合并”以在合并编辑器中将其打开。

  • 在合并编辑器中,“源”窗格显示源分支文件版本,“目标”窗格显示目标分支文件版本,“结果”窗格显示生成的合并文件。 若要应用特定的源或目标分支更改,请选中要保留的冲突行旁边的复选框。 还可以直接在“结果”窗格中编辑合并文件。 解决当前文件中的所有合并冲突后,选择“接受合并”。 对存在内容冲突的每个文件重复此步骤。

  • 对于在一个分支中编辑并在另一个分支中删除的文件,请选择所需的分支操作。

  • 在“解决冲突”视图中,在解决所有文件的所有合并冲突后,选择“提交合并”。

  • 在团队资源管理器的“更改”视图中,输入一个提交消息并选择“提交已暂存内容”以完成合并。

    在将源分支合并到目标分支之前,签出目标分支。 然后,使用 Git merge 命令将源分支合并到当前本地分支(目标分支)。 若要将多个源分支合并到目标分支中,使用空格分隔源分支名称。

    git checkout <target branch>
    git merge <source branch>
    

    还可以使用 git switch <branch name> 切换到分支。

    某些场景会导致 Git merge 命令失败并出现错误,或在完成之前停止。

    Git 消息 对下列文件的本地更改将被合并覆盖... 此错误指示当前本地分支有一个或多个包含未提交的更改的文件,并且这些文件受合并的影响。 Git 不会对不受合并影响的文件中的未提交的更改生成错误。 提交、储藏或放弃未提交的更改,然后重试合并。 自动合并失败;修复冲突,然后提交结果。 至少一个源分支更改与一个目标分支更改冲突。 Git 停止合并,等待你解决合并冲突。 通过运行 git merge --abort 来取消合并,或者解决所有合并冲突,然后运行 git merge --continue=======>>>>>>> 之间的文本是冲突文本的源分支版本。

  • 编辑文件以解决冲突文本。 通过删除合并冲突标记,可以让 Git 知道你已解决冲突。 例如,可以将前面的文本(包括冲突标记)更改为:

    - Network controller
    - Fiber optic transmitter
    - Fiber optic transceiver
    - Network switch
    
  • 解决所有冲突文本后,运行 git add <filename> 暂存文件。

  • 对存在内容冲突的所有文件重复上述步骤。

    解决删除-修改的文件冲突

    当同一个文件在一个分支中被编辑,但在另一个分支中被删除时,就会发生删除-修改的文件冲突。 对于每个删除-修改的文件,确定要使用哪个分支操作。 然后,使用 git add <filename> 保留修改的文件,或使用 git rm <filename> 删除该文件。

    通过推送共享代码撤消更改

  • 不熟悉 Git 存储库? 了解更多
  • 通过提取、合并和拉取更新代码
  • 使用提交保存工作
  •