代码冲突通常发生在团队协作中,多个开发者在同一分支上并行工作,修改了相同文件的相同部分。

场景描述

假设我们有一个 Git 仓库,分支为 main,文件 example.txt 内容如下:

1
Hello, this is a demo file.

开发者 A 和开发者 B 同时在这个 main 分支上工作,且他们都在本地对文件 example.txt 进行了修改。

步骤 1:开发者 A 的操作

开发者 A 修改了 example.txt 文件,添加了一行内容:

1
2
Hello, this is a demo file.
Feature A is implemented.

然后,开发者 A 提交了修改并推送到远程仓库:

1
2
3
git add example.txt
git commit -m "Developer A added feature A"
git push origin main

此时,开发者 A 的修改已成功提交并推送到了远程仓库。

步骤 2:开发者 B 的操作

与此同时,开发者 B 也在本地对 example.txt 进行了修改,添加了不同的内容:

1
2
Hello, this is a demo file.
Feature B is implemented.

开发者 B 提交了修改:

1
2
git add example.txt
git commit -m "Developer B added feature B"

然后,开发者 B 尝试将更改推送到远程仓库:

1
git push origin main

步骤 3:冲突发生

此时,Git 检测到远程仓库中的 main 分支有新的更改(即开发者 A 已经推送的修改),并且开发者 B 的修改与远程仓库中的内容有冲突。Git 会提示开发者 B 必须先拉取最新的远程仓库的更新再进行推送:

1
2
3
4
5
6
7
To [remote-repo]
! [rejected] main -> main (fetch first)
error: failed to push some refs to '[remote-repo]'
hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.

开发者 B 需要执行 git pull 命令来获取远程仓库中的更改:

1
git pull origin main

在拉取远程仓库的更改时,Git 发现开发者 A 和开发者 B 都修改了 example.txt 文件的同一个地方,因此会产生冲突。Git 会提示冲突,并在 example.txt 文件中标记冲突部分:

1
2
3
Auto-merging example.txt
CONFLICT (content): Merge conflict in example.txt
Automatic merge failed; fix conflicts and then commit the result.

此时,打开 example.txt 文件,你会看到如下内容:

1
2
3
4
5
6
Hello, this is a demo file.
<<<<<<< HEAD
Feature B is implemented.
=======
Feature A is implemented.
>>>>>>> [commit-id]

这里的 <<<<<<< HEAD 表示开发者 B 的本地修改,=======>>>>>>> [commit-id] 表示远程仓库中的修改(开发者 A 的提交)。

解决冲突

方案 1:手动解决冲突

开发者 B 需要手动编辑 example.txt 文件来解决冲突。例如,合并两个修改,将文件内容改为:

1
2
3
Hello, this is a demo file.
Feature B is implemented.
Feature A is implemented.

然后保存文件,并执行以下命令来标记冲突已解决:

1
2
git add example.txt
git commit -m "Resolved conflict between feature A and feature B"

最后,开发者 B 可以成功推送更改到远程仓库:

1
git push origin main

方案 2:放弃本地更改

如果开发者 B 决定放弃自己本地的修改,直接采用远程仓库的内容,可以使用以下命令:

1
git reset --hard origin/main

这会丢弃本地的未推送的更改,并将本地代码回滚到与远程仓库一致的状态。之后,开发者 B 可以重新修改代码或继续其他开发工作。

总结

在同一分支(如 main)上出现代码冲突的常见原因是多个开发者并行修改了同一个文件的同一个部分。解决办法通常是: 1. 手动解决冲突:修改冲突文件,将两者的更改合理合并。 2. 放弃本地更改:如果不需要保留本地修改,可以直接丢弃本地改动,采用远程的内容。