跳到内容

元数据卡: 前置知识:ch03-git-branch.md | 预计时间:10 分钟 | 完成标志:能独立解决一个合并冲突

第四场战斗:两个人改了同一行

前面几次合并都挺顺利的——你只是往主干上叠加新的零件图,跟已有的方案不冲突。但这次不一样了。

你在自己的工位上改了一个零件的尺寸,隔壁工位的同事也在他的工位上改了同一个零件的尺寸。你俩的改动方向完全相反。

"合到一起试试?"你的同事说。

你把两份图纸放上操作台,运行了比对。操作台沉默了一秒——然后弹出了一行红色的标记:

冲突

"什么叫冲突?"你有点慌了。

你和同事修改了同一张图纸上的同一处尺寸。你说"这个接口要用圆形",他说"要改成方形"。你们各自把版本登记进了工坊日志。现在你要把两个设计合到一起——操作台困惑了:"你俩到底谁对?"

这就是合并冲突


制造一个冲突

空说无凭,我们来亲手制造一个冲突:

bash
# 从 master 创建 feature-a 分支
git switch -c feature-a
echo "a" > main.py
git add main.py && git commit -m "feature-a: change to a"

# 回到 master,创建 feature-b 分支
git switch master
git switch -c feature-b
echo "b" > main.py
git add main.py && git commit -m "feature-b: change to b"

现在回到 master,先合并 feature-a,再合并 feature-b

bash
git switch master
git merge feature-a
git merge feature-b

语言: Bash 如何运行: 按顺序粘贴到终端 预期输出(第二条 merge 命令):

Auto-merging main.py
CONFLICT (content): Merge conflict in main.py
Automatic merge failed; fix conflicts and then commit the result.

看到 CONFLICT 了吗?Git 很诚实地说:"我没法替你做决定。"


看看冲突长什么样

打开 main.py,你会看到 Git 留下的标记:

python
<<<<<<< HEAD
b
=======
a
>>>>>>> feature-b

这是 Git 在说:

  • <<<<<<< HEAD======= 之间:当前分支(master)的版本——内容是 b
  • =======>>>>>>> feature-b 之间:要合并进来的分支的版本——内容是 a

现在你需要做三件事:

  1. 删掉所有 Git 标记:<<<<<<<=======>>>>>>>
  2. 改成你想要的内容(保留一个、保留两个、或者重写)
  3. 保存文件,然后 git add + git commit
bash
# 假设我决定两边都要
echo -e "a\nb" > main.py
git add main.py
git commit -m "resolve merge conflict: keep both a and b"

语言: Bash 预期输出:

[master d7e8f9g] resolve merge conflict: keep both a and b

冲突解决完成。

核心原则: Git 不会替你解决语义上的冲突("a 还是 b 对?"),它只解决文本上的冲突("这行有两个版本")。合并冲突不是 bug——它是 Git 诚实地说"我搞不定了,你来决定"。

试试看: 按上面的步骤亲手造一次冲突,然后打开 main.py 看看 <<<<<<< 标记长什么样。把它改成你想要的版本,add + commit 完成解决。


放弃合并

合并到一半,你觉得不对劲——改动太大,不想合了?Git 允许你放弃:

bash
# 放弃当前正在进行的合并,回到合并前的状态
git merge --abort

试试看:git merge 出现冲突后,运行 git merge --abort,确认文件回到了合并前的样子。


冲突不是灾难

很多新手第一次看到 CONFLICT 就慌了,觉得"代码坏了""做错了什么"。但恰恰相反:

  • 冲突 = Git 如实告诉你它没法自动合并
  • 没有冲突 = Git 自动做了决定,你可能没发现它合错了

冲突是 Git 诚实谦逊的表现。 它知道自己不擅长替你做决定,所以把最困难的部分——语义判断——留给了你。


用图形工具解决冲突

如果你觉得在文本编辑器里手动找 <<<<<<< 标记太麻烦(特别是冲突文件很大时),Git 支持可视化合并工具:

bash
# 启动配置的合并工具(如 vimdiff、meld、kdiff3)
git mergetool

VSCode 内置了合并冲突编辑器,打开冲突文件会看到三个面板:

  • 当前分支(左边)
  • 要合并的分支(右边)
  • 合并结果(中间)

你只需要点击"采纳当前""采纳传入"或"同时保留"按钮。这让解决冲突直观得多。


下一步

你在自己的工坊里用 Git 越来越顺手了。但你终究会遇到一个需求——把代码分享给别人。或者从别人那里拉代码。

下一节,我们连接 远程仓库——把你的工坊和世界的工坊连通。

继续:远程仓库协作

Built with VitePress | Software Systems Atlas