Skip to content

处理冲突

概述

在团队协作中,多人同时修改同一文件时不可避免地会产生冲突。理解冲突产生的原因、掌握解决冲突的方法、制定预防策略,是高效协作的关键。

远程冲突场景

场景一:同时修改同一文件

情况描述

开发者 A 和开发者 B 同时修改 config.js 文件。

时间线:
T1: A 拉取最新代码
T2: B 拉取最新代码
T3: A 修改 config.js 并推送
T4: B 修改 config.js 并推送 ← 冲突!

冲突表现

bash
git push origin main

输出:

! [rejected]        main -> main (non-fast-forward)
error: failed to push some refs to 'git@github.com:user/repo.git'

场景二:修改同一文件的不同位置

情况描述

开发者 A 修改文件开头,开发者 B 修改文件末尾。

冲突表现

Git 通常可以自动合并,但如果修改相邻,可能产生冲突。

场景三:修改同一行代码

情况描述

两个开发者修改同一文件的同一行。

冲突表现

bash
git pull origin main

输出:

CONFLICT (content): Merge conflict in src/app.js
Automatic merge failed; fix conflicts and then commit the result.

场景四:文件删除与修改冲突

情况描述

开发者 A 删除文件,开发者 B 修改同一文件。

冲突表现

CONFLICT (modify/delete): src/old-module.js deleted in main and modified in HEAD

场景五:重命名冲突

情况描述

开发者 A 重命名文件,开发者 B 修改原文件名。

冲突表现

CONFLICT (rename/rename): src/old-name.js renamed to src/new-name.js in main and to src/other-name.js in HEAD

解决远程冲突

方法一:拉取并合并

步骤

bash
git fetch origin
git merge origin/main

查看冲突文件:

bash
git status

解决冲突:

bash
git add <resolved-files>
git commit
git push origin main

方法二:拉取并变基

步骤

bash
git fetch origin
git rebase origin/main

查看冲突:

bash
git status

解决冲突:

bash
git add <resolved-files>
git rebase --continue

推送:

bash
git push origin main

方法三:使用合并工具

配置合并工具

bash
git config --global merge.tool vscode
git config --global mergetool.vscode.cmd 'code --wait $MERGED'

启动合并工具

bash
git mergetool

详细解决步骤

1. 查看冲突状态

bash
git status

输出:

Unmerged paths:
  (use "git add <file>..." to mark resolution)
    both modified:   src/app.js

2. 查看冲突内容

bash
git diff

或直接打开文件:

<<<<<<< HEAD
const apiUrl = 'https://api.example.com/v2';
=======
const apiUrl = 'https://api.example.com/v1';
>>>>>>> origin/main

3. 手动解决冲突

编辑文件,保留正确的内容:

javascript
const apiUrl = 'https://api.example.com/v2';

4. 标记冲突已解决

bash
git add src/app.js

5. 完成合并/变基

合并:

bash
git commit

变基:

bash
git rebase --continue

6. 推送代码

bash
git push origin main

使用策略自动解决

选择本地版本

bash
git checkout --ours src/app.js

选择远程版本

bash
git checkout --theirs src/app.js

合并时指定策略

bash
git merge origin/main -X ours
git merge origin/main -X theirs

放弃合并

放弃正在进行的合并

bash
git merge --abort

放弃正在进行的变基

bash
git rebase --abort

避免冲突策略

频繁同步

每天至少同步一次

bash
git fetch origin
git rebase origin/main

推送前先拉取

bash
git fetch origin
git rebase origin/main
git push origin feature-branch

使用功能分支

不在主分支直接开发

bash
git checkout -b feature/user-auth

每个功能独立分支

bash
git checkout -b feature/login
git checkout -b feature/register
git checkout -b feature/profile

小步提交

频繁提交小改动

bash
git add src/auth.js
git commit -m "feat: add login validation"
git push origin feature/auth

git add src/user.js
git commit -m "feat: add user session"
git push origin feature/auth

模块化设计

按功能模块划分文件

src/
  auth/
    login.js
    register.js
  user/
    profile.js
    settings.js
  api/
    client.js
    endpoints.js

团队沟通

提前通知

  • 即将修改公共文件时通知团队
  • 使用项目管理工具分配任务
  • 避免同时修改同一模块

代码所有者

创建 .github/CODEOWNERS

/src/auth/ @auth-team
/src/api/ @api-team

使用锁文件

对于配置文件等易冲突文件:

bash
git lfs lock config.json

修改完成后解锁:

bash
git lfs unlock config.json

冲突预防

代码架构层面

单一职责原则

每个模块只负责一个功能,减少交叉修改。

接口隔离

通过接口通信,减少直接依赖。

模块化开发

features/
  feature-a/
    index.js
    styles.css
  feature-b/
    index.js
    styles.css

流程层面

分支策略

main
  └── develop
        ├── feature/a
        ├── feature/b
        └── feature/c

代码审查

通过 PR 审查提前发现潜在冲突。

持续集成

自动化测试确保合并后代码正确。

工具层面

Git 钩子

bash
#!/bin/bash
git fetch origin
git diff --quiet HEAD origin/main || echo "Warning: Remote has updates"

自动化脚本

bash
#!/bin/bash
before_push() {
    git fetch origin
    git rebase origin/main
    echo "Synced with remote"
}

高级冲突处理

复杂冲突场景

多文件冲突

bash
git status

逐个解决:

bash
git add file1.js
git add file2.js
git commit

二进制文件冲突

bash
git checkout --ours images/logo.png
git add images/logo.png

子模块冲突

bash
git submodule update --init --recursive

使用 git rerere

启用 rerere(重用已解决的冲突):

bash
git config --global rerere.enabled true

Git 会记住冲突的解决方案,下次遇到相同冲突时自动应用。

交互式变基解决冲突

bash
git rebase -i origin/main

可以重新排序、合并或编辑提交,减少冲突。

冲突解决工作流

标准工作流

bash
git fetch origin
git checkout feature/my-feature
git rebase origin/main

git status
git diff

git add <resolved-files>
git rebase --continue

git push origin feature/my-feature --force-with-lease

PR 冲突解决工作流

bash
git fetch origin
git checkout feature/my-feature
git merge origin/main

git mergetool

git add .
git commit
git push origin feature/my-feature

紧急修复冲突工作流

bash
git stash
git fetch origin
git checkout main
git pull origin main
git checkout -b hotfix/urgent-fix

git add .
git commit -m "fix: urgent fix"
git push origin hotfix/urgent-fix

git stash pop

最佳实践总结

预防优于解决

  • 频繁同步主分支
  • 使用功能分支开发
  • 小步提交,频繁推送
  • 模块化代码架构

解决要彻底

  • 理解冲突原因
  • 测试解决结果
  • 保持代码一致性

沟通是关键

  • 提前通知团队
  • 及时响应冲突
  • 记录解决方案

总结

  • 冲突是团队协作的常态,不必恐惧
  • 理解冲突类型,选择合适的解决方法
  • 频繁同步、小步提交是预防冲突的关键
  • 使用功能分支隔离开发
  • 建立团队沟通机制
  • 掌握合并工具提高解决效率