人人都能学编程
English 开始学习
核心 · Git第 4 课 / 共 6 课免费阅读

合并冲突 · Git 与 GitHub

两处修改撞在一起时怎么办?

课程目录

为什么需要它

两个人改了同样的行,Git 不知道哪个版本才对,于是停下来问你。冲突在任何团队里都很正常,不代表出了大事;掌握步骤后,冷静地解决一个只需要一分钟。

直觉理解

Git 会在文件里标出冲突:

<<<<<<< HEAD
你的版本(你当前所在的分支)
=======
他们的版本(你要合并进来的分支)
>>>>>>> new-title

步骤永远是:

  1. git status:哪些文件冲突了?
  2. 编辑每个文件:保留一边、另一边或者两者结合,并且删掉标记行。
  3. git add 文件 标记为已解决。
  4. git commit 完成合并。

改主意了?git merge --abort 能把一切恢复到合并之前。

定义

合并冲突

Both branches changed the same part of a file. Git stops the merge until you choose the result.
两个分支改了文件的同一部分。Git 会暂停合并,直到你决定最终结果。

冲突标记

The lines <<<<<<<, ======= and >>>>>>> that Git writes into a file to show both versions. They must be removed before you commit.
Git 写进文件、用来显示两个版本的 <<<<<<<、=======、>>>>>>> 这几行。提交前必须删掉。

示例

main 把商店改了名,new-title 改成了另一个名字。合并,然后看看。

git merge new-title
git status
cat README.md
逐步执行
  1. L1CONFLICT:Git 停在半路。
  2. L2README.md 被标为 both modified(双方都改了)。
  3. L3两个版本都在,夹在标记之间。<<<<<<< HEAD

写好最终版本,标记为已解决,提交。

git merge new-title
echo "# My Best Shop" > README.md
git add README.md
git commit -m "merge new-title"
git log --oneline
逐步执行
  1. L2最终的文字,没有任何标记。
  2. L3add 的意思是:这个冲突解决了。
  3. L4合并提交让合并完成。

常见错误

把标记也提交了

如果文件里还有 <<<<<<<,你就提交了一个坏掉的文件。git add 之前先搜一下。

习惯性只保留自己的版本

另一边的修改也是有原因的。两边都读一读;正确答案常常是把它们结合起来。

小测验

1. 你改好了文件。用什么告诉 Git 冲突解决了?

  1. Agit add 文件
  2. B再 git merge 一次
  3. Cgit restore 文件
查看答案

答案:A

暂存改好的文件就是标记为已解决;然后提交。

2. 最后一条命令打印什么?

git merge new-title
git merge --abort
cat README.md
  1. A
    # My Shop
  2. B
    # Best Shop
  3. C
    <<<<<<< HEAD
    # My Shop
    =======
    # Best Shop
    >>>>>>> new-title
查看答案

答案:A

--abort 恢复到合并之前的样子:main 的版本。

动手练习

3 道练习,分三层:先预测程序的输出,再按新需求改程序,最后从零写一个。代码在浏览器里运行,提交马上判题。

  1. 预测输出读懂标记

    这次合并后,标记之间哪一行来自 new-title 分支?

  2. 改需求完成合并

    这里解决了冲突,但漏了两步,所以合并一直没完成。把它们补上,让合并以 merge new-title 为说明提交。

  3. 从零写两个想法都保留

    把 new-title 合并进 main,解决冲突,让 README.md 只包含一行 # My Best Shop。提交这次合并。

在互动课里练这一课

打开互动课,这些例子都能直接改、直接运行,练习题提交马上判题。免费开始,不用注册。

互动课按顺序解锁:前面的课还没学,会先带你到课程地图。

本课术语

术语中文英文定义
Merge conflict合并冲突Two branches changed the same lines; you choose the result.
Abort中止Cancel an operation and go back to before it started.