Git 冲突解决完全指南

基础
视频演示

Git 冲突解决完全指南

📚 目录

  1. 什么是冲突
  2. 为什么会产生冲突
  3. 如何预防冲突
  4. 冲突解决步骤
  5. 实战演示
  6. 常见错误和陷阱
  7. 最佳实践

什么是冲突

简单理解

冲突 = Git 不知道如何自动合并你的修改

情况1:无冲突(Git 可以自动合并)
─────────────────────────────────
服务器版本:       你的版本:
第10行:name      第10行:username
第20行:age       第20行:age
结果:✅ Git 自动合并(修改了不同行)

情况2:有冲突(Git 无法自动合并)
─────────────────────────────────
服务器版本:       你的版本:
第10行:name      第10行:username
第20行:age       第20行:birthday
结果:❌ 冲突(修改了同一行或相邻行)

冲突标记

Git 会在冲突文件中插入标记:

<<<<<<< HEAD
# 这是你当前分支的版本(你本地的代码,可能是你之前写的或之前拉取的)
name = "Alice"
age = 25
=======
# 这是要合并进来的版本(通常是服务器上的新代码,别人提交的)
username = "Alice"
birthday = "1998-01-01"
>>>>>>> branch-name

标记说明:

  • <<<<<<< HEAD - 冲突开始,HEAD 表示你当前分支的代码(你本地的状态)
  • ======= - 分隔线(上面是你当前分支的版本,下面是要合并进来的版本)
  • >>>>>>> branch-name - 冲突结束,branch-name 是要合并进来的分支名称(通常是 origin/main 等,表示服务器上的代码)

为什么会产生冲突

常见场景

场景1:多人修改同一文件

时间线:
1. 你拉取代码:app.py 第10行是 name = "Alice"
2. 你修改:改成 username = "Alice"
3. 同事也修改:改成 fullname = "Alice"
4. 同事先推送
5. 你拉取时:Git 发现第10行被两个人改了 → 冲突!

场景2:你修改了,别人删除了

时间线:
1. 你修改了 utils.py 的某个函数
2. 同事删除了这个文件
3. 你拉取时:Git 不知道保留还是删除 → 冲突!

场景3:合并分支时

main 分支:        feature 分支:
app.py 第10行      app.py 第10行
name = "Alice"     username = "Alice"
↓ 合并时
冲突!

如何预防冲突

策略1:频繁拉取和推送

# ❌ 不好的习惯
git pull    # 一周拉取一次
# 修改很多代码...
git push    # 冲突概率很高
 
# ✅ 好的习惯
git pull    # 每天开始工作前
# 修改代码...
git add .
git commit
git push    # 及时推送
git pull    # 推送前再拉取一次

策略2:小步提交

# ❌ 不好的习惯
# 修改了1000行代码,一次性提交
git commit -m "Big change"
 
# ✅ 好的习惯
# 完成一个小功能就提交
git commit -m "Add user validation"
git commit -m "Update login logic"
git commit -m "Fix bug in auth"

策略3:沟通和分工

团队协作:
- 提前沟通:谁负责哪个文件
- 分工明确:避免多人同时修改同一文件
- 使用分支:不同功能用不同分支

策略4:使用分支

# 为每个功能创建独立分支
git checkout -b feature/user-login
# 开发完成后合并
git checkout main
git pull
git merge feature/user-login

冲突解决步骤

标准流程(记住这个!)

1. 发现冲突
   ↓
2. 查看冲突文件
   ↓
3. 理解冲突内容
   ↓
4. 手动解决冲突(编辑文件)
   ↓
5. 标记为已解决(git add)
   ↓
6. 完成合并(git commit)

详细步骤

步骤1:发现冲突

git pull origin main
# 输出:
# Auto-merging app.py
# CONFLICT (content): Merge conflict in app.py
# Automatic merge failed; fix conflicts and then commit the result.

步骤2:查看冲突状态

git status
# 输出:
# Unmerged paths:
#   (use "git add <file>..." to mark as resolved)
#         both modified:   app.py

步骤3:打开冲突文件,查看冲突

# app.py
def get_user():
<<<<<<< HEAD
    name = "Alice"
    age = 25
=======
    username = "Alice"
    birthday = "1998-01-01"
>>>>>>> origin/main
    return user

步骤4:手动解决冲突(3种选择)

选择1:保留服务器版本(HEAD)

def get_user():
    name = "Alice"
    age = 25
    return user

选择2:保留你的版本

def get_user():
    username = "Alice"
    birthday = "1998-01-01"
    return user

选择3:合并两者(最常用)

def get_user():
    username = "Alice"
    age = 25
    birthday = "1998-01-01"
    return user

重要:删除所有冲突标记!

# ❌ 错误:保留冲突标记
<<<<<<< HEAD
name = "Alice"
=======
username = "Alice"
>>>>>>> origin/main
 
# ✅ 正确:删除所有标记,只保留最终代码
username = "Alice"

步骤5:标记为已解决

git add app.py
# 告诉 Git:这个文件的冲突已经解决了

步骤6:完成合并

git commit
# Git 会自动创建一个合并提交
# 或者使用:
git commit -m "Resolve merge conflict in app.py"

实战演示

演示1:创建冲突场景

让我们创建一个实际的冲突场景来练习:

# 1. 创建测试仓库
mkdir conflict-demo
cd conflict-demo
git init
 
# 2. 创建初始文件
echo "name = 'Alice'" > app.py
git add app.py
git commit -m "Initial commit"
 
# 3. 创建分支(模拟同事的修改)
git checkout -b colleague-branch
echo "username = 'Alice'" > app.py
git add app.py
git commit -m "Change name to username"
 
# 4. 切换回主分支(模拟你的修改)
git checkout main
echo "fullname = 'Alice'" > app.py
git add app.py
git commit -m "Change name to fullname"
 
# 5. 尝试合并(会产生冲突)
git merge colleague-branch
# CONFLICT!

演示2:解决冲突

# 1. 查看冲突文件
cat app.py
# 输出:
# <<<<<<< HEAD
# fullname = 'Alice'
# =======
# username = 'Alice'
# >>>>>>> colleague-branch
 
# 2. 编辑文件,解决冲突
# 选择保留 username,删除冲突标记
echo "username = 'Alice'" > app.py
 
# 3. 标记为已解决
git add app.py
 
# 4. 完成合并
git commit -m "Resolve conflict: use username"

常见错误和陷阱

错误1:忘记删除冲突标记

# ❌ 错误
<<<<<<< HEAD
name = "Alice"
=======
username = "Alice"
>>>>>>> origin/main
# 代码无法运行!
 
# ✅ 正确
username = "Alice"

错误2:只解决了一部分冲突

# 有多个文件冲突
git status
# Unmerged: app.py, utils.py, config.py
 
# ❌ 错误:只解决了 app.py
git add app.py
git commit  # 会失败,还有其他冲突
 
# ✅ 正确:解决所有冲突
git add app.py utils.py config.py
git commit

错误3:解决冲突时引入了新错误

# 解决冲突时,不小心删除了重要代码
def get_user():
    # 删除了验证逻辑
    return user  # ❌ 缺少验证

解决方法:

  • 解决冲突后,运行测试
  • 检查代码逻辑
  • 让同事 review

错误4:使用错误的合并策略

# ❌ 错误:强制覆盖(会丢失代码)
git pull --rebase  # 如果不懂 rebase,不要用
git push --force   # 危险!会覆盖别人的代码
 
# ✅ 正确:正常合并
git pull
# 解决冲突
git add .
git commit
git push

最佳实践

1. 解决冲突的检查清单

□ 理解冲突的原因(为什么会有冲突?)
□ 查看两个版本的差异(git diff)
□ 与相关同事沟通(如果需要)
□ 手动解决冲突(删除所有标记)
□ 测试代码(确保没有引入错误)
□ 标记为已解决(git add)
□ 完成合并(git commit)

2. 使用工具帮助解决冲突

VS Code / Cursor

1. 打开冲突文件
2. 会显示冲突标记
3. 点击 "Accept Current Change" / "Accept Incoming Change" / "Accept Both"
4. 自动删除冲突标记

Git 命令查看差异

# 查看冲突的详细差异
git diff HEAD
git diff origin/main
 
# 查看合并前的状态
git diff --merge

3. 复杂冲突的处理

如果冲突很复杂:

# 1. 先中止合并,重新思考
git merge --abort
 
# 2. 查看两个分支的差异
git diff main..feature-branch
 
# 3. 与同事沟通
# 4. 重新合并
git merge feature-branch

4. 预防冲突的工作流

# 每天开始工作前
git pull origin main
 
# 修改代码
# ...
 
# 提交前
git pull origin main  # 再次拉取,确保最新
git add .
git commit -m "Your message"
git push origin main

快速参考

冲突解决命令速查

# 1. 发现冲突
git pull
# 或
git merge branch-name
 
# 2. 查看冲突文件
git status
 
# 3. 查看冲突内容
cat conflict-file.py
# 或
code conflict-file.py  # 用编辑器打开
 
# 4. 解决冲突后
git add conflict-file.py
 
# 5. 完成合并
git commit
 
# 6. 如果放弃合并
git merge --abort

冲突标记速查

<<<<<<< HEAD
# 当前分支的代码(或服务器版本)
=======
# 要合并进来的代码
>>>>>>> branch-name

记住:解决后要删除所有这三行!


总结

核心要点

  1. 冲突是正常的 - 多人协作时不可避免
  2. 解决冲突的步骤 - 查看 → 理解 → 解决 → 标记 → 提交
  3. 预防比解决更重要 - 频繁拉取、小步提交、良好沟通
  4. 删除冲突标记 - 这是最常见的错误
  5. 测试你的解决方案 - 确保没有引入新错误

心理建设

  • 不要害怕冲突,这是正常的
  • 冲突说明团队在积极开发
  • 解决冲突是学习的好机会
  • 遇到复杂冲突,及时求助

下一步

  1. 在实际项目中练习
  2. 遇到冲突时,参考这个指南
  3. 与团队建立冲突解决的标准流程
  4. 使用工具(VS Code/Cursor)简化操作

记住:解决冲突的核心是理解代码意图,然后做出正确的选择!