mcpField
R
resolve-conflicts

resolve-conflicts

github.com/tailcallhq开发7.6k684 次安装今天更新
代码仓库

关于 resolve-conflicts

面向编码 Agent 的 Git 合并冲突处理技能,先制定方案并获批,再执行合并与验证;尽可能保留两个分支的更改意图。

主要功能

  1. 01编辑前制定冲突解决计划
  2. 02获批并询问不明确之处
  3. 03尽可能合并双方更改
  4. 04从源文件重新生成生成文件
  5. 05为删除-修改冲突创建备份
  6. 06验证冲突解决并运行测试

适用场景

  1. 01处理多种文件类型的冲突
  2. 02备份并分析删除-修改文件
  3. 03合并测试、导入项和配置
  4. 04提交前检查冲突是否解决

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/tailcallhq/forgecode --skill resolve-conflicts

安装后在 Claude Code 中输入/resolve-conflicts确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
patterns.md
sample-plan.md
scripts/
handle-deleted-modified.sh
validate-conflicts.sh

详细介绍

Git 冲突解决

通过智能合并两个分支的更改来解决 Git 合并冲突,同时保留双方更改的意图。本技能采用先规划的方法:评估冲突、制定详细的解决计划、获得批准,然后执行。

核心原则

  1. 先规划,再执行:始终制定结构化的解决计划,并在进行更改前获得用户批准
  2. 优先保留双方更改:默认保留双方的更改,除非它们直接矛盾
  3. 合并,而不是择一:尤其是导入项、测试和配置
  4. 重新生成生成文件:绝不手动合并生成文件;始终从源文件重新生成
  5. 解决前先备份:对于删除-修改冲突,先创建备份
  6. 通过测试进行验证:解决冲突后始终运行测试
  7. 说明所有解决方式:对于解决的每个冲突,用一行说明所采用的解决策略
  8. 有疑问时询问:如果无法从差异中明确正确的解决方式,请向用户列出选项并询问其选择

工作流

步骤 1:评估冲突情况

运行初始检查以了解冲突范围:

git status

识别并分类所有冲突文件:

  • 常规文件冲突(双方均已修改)
  • 删除-修改冲突(一方删除,一方修改)
  • 生成文件冲突(锁文件、构建产物、生成代码)
  • 测试文件冲突
  • 导入项/配置冲突
  • 二进制文件冲突

对于每个冲突文件,收集以下信息:

  • 文件类型和用途
  • 冲突性质(内容、删除、类型变更)
  • 更改范围(更改的行数、受影响的部分)
  • 文件是生成的还是手动编写的
步骤 2:制定合并冲突解决计划

根据评估结果,在解决任何冲突之前制定结构化计划。按以下 Markdown 格式展示计划:

## Merge Resolution Plan

### Conflict Summary

- **Total conflicted files**: [N]
- **Deleted-modified conflicts**: [N]
- **Generated files**: [N]
- **Regular conflicts**: [N]

### Resolution Strategy by File

#### 1. [File Path]

**Conflict Type**: [deleted-modified / generated / imports / tests / code logic / config / struct / binary]
**Strategy**: [Brief description of resolution approach]
**Rationale**: [Why this strategy is appropriate]
**Risk**: [Low/Medium/High] - [Brief risk description]
**Action Items**:

- [ ] [Specific action 1]
- [ ] [Specific action 2]

#### 2. [File Path]

...

### Execution Order

1. **Phase 1: Deleted-Modified Files** - Handle deletions and backups first
2. **Phase 2: Generated Files** - Regenerate from source
3. **Phase 3: Low-Risk Merges** - Imports, tests, documentation
4. **Phase 4: High-Risk Merges** - Code logic, configuration, structs
5. **Phase 5: Validation** - Compile, test, verify

### Questions/Decisions Needed

- [ ] **[File/Decision]**: [Question for user] (Options: 1, 2, 3)

### Validation Steps

- [ ] Run conflict validation script
- [ ] Compile project
- [ ] Run test suite
- [ ] Manual verification of high-risk changes

向用户展示此计划,并在继续解决前等待批准。如果有任何需要用户提供意见的未明确冲突,请将其列在“需要回答的问题/决定”部分。

完整计划示例请参见 references/sample-plan.md。

步骤 3:处理删除-修改文件

仅在计划获批后执行此阶段。

如果存在已删除但已修改的文件(状态:DU、UD、DD、UA、AU):

.forge/skills/resolve-conflicts/scripts/handle-deleted-modified.sh

此脚本将:

  • 为已修改的内容创建带时间戳的备份
  • 分析可能的迁移目标
  • 为每个文件生成分析报告
  • 自动解决删除状态

查看备份目录和分析文件,了解应在何处应用更改。

步骤 4:执行解决计划

按照计划中定义的执行顺序操作。 对每个冲突文件,根据计划应用相应的解决模式。对于解决的每个冲突,用一行说明如何解决。

完成计划中的每项操作后,将其标记为已完成,并向用户报告进度。

解决方式不明确时

如果仅凭差异无法确定正确的解决方式(这类情况应已列在计划的“需要回答的问题/决定”部分):

  1. 向用户展示冲突,并附上双方冲突的代码
  2. 列出带编号的选项(选项 1、选项 2 等)
  3. 清楚说明每个选项及其作用
  4. 请用户选择一个选项编号或提供更多信息
  5. 记住用户的选择,并将类似的推理应用于后续相关冲突

交互示例:

I found a conflict in src/main.rs where both branches modify the `calculate_price` function:

<<<<<<< HEAD (Current Branch)
fn calculate_price(item: &Item) -> f64 {
    item.base_price * (1.0 + item.tax_rate)
}
=======
fn calculate_price(item: &Item) -> f64 {
    item.base_price + item.tax_amount
}
>>>>>>> feature-branch (Incoming Branch)

I'm not sure which calculation is correct. Please select an option:

**Option 1**: Keep current branch (multiplies base_price by tax_rate)
**Option 2**: Keep incoming branch (adds tax_amount to base_price)
**Option 3**: Keep both approaches with a new parameter
**Option 4**: Provide more context to help me decide

Please respond with "Option 1", "Option 2", "Option 3", or "Option 4", or provide additional information.

用户回复后,应用其决定,并将类似逻辑用于相关冲突。

解决模式

对于每个冲突文件,应用相应的解决模式:

导入/依赖项

目标:合并两个分支中的所有唯一导入项。

一句话说明:“合并导入项:整合两个分支中的唯一导入项、移除重复项,并按模块分组。”

阅读 references/patterns.md 中的“导入冲突”部分,查看详细示例。

快速处理方法:

  1. 提取两侧的所有导入项
  2. 移除重复项
  3. 按模块/包分组
  4. 遵循特定语言的风格(按字母顺序排列、区分标准库/外部库/内部模块)
测试

目标:纳入两个分支中的所有测试用例和测试数据。

一句话说明:“合并测试:纳入两个分支中的所有测试用例、合并测试固件,并在必要时重命名以避免冲突。”

阅读 references/patterns.md 中的“测试冲突”部分,查看详细示例。

快速处理方法:

  1. 保留所有测试函数,除非它们测试的内容完全相同
  2. 合并测试固件和设置函数
  3. 整合两侧的断言
  4. 如果测试名称冲突,但测试的是不同的行为,则重命名以明确区分
生成文件

目标:重新生成所有生成文件,以纳入两个分支中的更改。

一句话说明:“解决生成文件冲突:从源文件重新生成文件,以纳入两个分支中的更改。”

识别方法:满足以下条件的文件属于生成文件:

  • 由构建工具、编译器或代码生成器生成
  • 有对应的源文件或配置来定义它
  • 包含表明其为自动生成文件的头部信息/注释
  • 在 .gitattributes 中被列为生成文件
  • 常见示例:锁定文件、protobuf 输出文件、GraphQL 架构文件、编译后的资源、自动生成的文档

处理方法:

  1. 确定生成源:确认生成该文件的命令或工具

  2. 暂时选择任一版本(选择哪个都无关紧要):

    git checkout --ours <generated-file>    # or --theirs
    
  3. 从源文件重新生成:运行相应的生成命令:

    # Package manager lock files
    cargo update                       # for Cargo.lock
    npm install                        # for package-lock.json
    yarn install                       # for yarn.lock
    bundle install                     # for Gemfile.lock
    poetry lock --no-update            # for poetry.lock
    
    # Code generation
    protoc ...                         # for protobuf files
    graphql-codegen                    # for GraphQL generated code
    make generate                      # for Makefile-based generation
    npm run generate                   # for npm script-based generation
    
    # Build artifacts
    npm run build                      # for compiled/bundled assets
    cargo build                        # for Rust build artifacts
    
  4. 暂存重新生成的文件:

    git add <generated-file>
    

不确定文件是否为生成文件时:检查文件头部是否有自动生成标记,或者询问用户应重新生成该文件还是手动合并。

配置文件

目标:合并两个分支中的配置值。

一句话说明:“合并配置:纳入两个分支中的所有键,并为冲突选择合适的值。”

阅读 references/patterns.md 中的“配置文件冲突”部分,查看详细示例。

快速处理方法:

  1. 纳入两侧的所有键
  2. 对于冲突的值,根据以下因素选择:
    • 更新/更近期的值
    • 更安全/更保守的值
    • 生产环境要求
  3. 在提交消息中说明选择依据

不明确时:询问用户应优先采用哪个配置值(当前值还是传入值)

代码逻辑

目标:理解两项更改的意图,并尽可能将它们结合起来。

一句话说明:“解决代码逻辑冲突:分析更改意图;如果更改涉及不同方面,则合并;如果更改相互冲突,则选择一种方案。”

阅读 references/patterns.md 中的“代码逻辑冲突”部分,查看详细示例。

快速处理方法:

  1. 分析每个分支要实现的目标
  2. 如果更改涉及不同方面,则合并两者
  3. 如果更改相互冲突(关注点相同,但方案不同):
    • 查看提交消息/PR,了解背景
    • 选择符合需求的方案
    • 如果不明确,则测试两种方案
    • 说明决定的依据

不明确时:向用户介绍两种方案,并说明各自的作用

Struct/类型定义

目标:包含两个分支中的所有字段。

一句话说明:“合并 struct,包含两个分支中的所有字段,并为任何冲突的字段定义选择合适的类型。”

快速处理方法:

  1. 合并所有字段
  2. 如果字段类型冲突,分析哪种类型更合适
  3. 修复更新 struct 后出现的所有编译错误
  4. 更新测试以使用新字段

不确定时:如果字段类型冲突,询问用户哪种类型定义才是正确的

第 5 步:验证解决结果

完成计划中的所有解决阶段后,验证所有冲突均已解决:

.forge/skills/resolve-conflicts/scripts/validate-conflicts.sh

此脚本会检查:

  • 剩余的冲突标记(<<<<<<<、=======、>>>>>>>)
  • git status 中尚未合并的路径
  • 已删除-已修改冲突
  • 合并状态文件
第 6 步:编译和测试

按照计划中的验证步骤进行构建和测试,确保解决结果正确:

# For Rust projects
cargo test

# For other projects, use appropriate test command
# npm test
# pytest
# etc.

如果测试失败:

  1. 检查失败情况——问题来自合并后的代码还是冲突解决?
  2. 检查两个分支的测试是否各自单独通过
  3. 修复合并更改之间的集成问题
  4. 重新运行测试,直到全部通过
第 7 步:完成

解决所有冲突且测试通过后,检查已完成的计划并提交:

# Review the changes
git diff --cached

# Commit with descriptive message that references the plan
git commit -m "Resolve merge conflicts: [describe key decisions]

Executed merge resolution plan:
- [Phase 1 summary]
- [Phase 2 summary]
- [Phase 3+ summaries]

Key decisions:
- Merged imports from both branches
- Combined test cases
- Regenerated lock files
- [other significant decisions from plan]

Co-Authored-By: ForgeCode <[email protected]>"

决策跟踪

当你让用户在多个选项中做出选择时,记录其决定,并在后续冲突中采用类似的推理方式:

场景示例:

  1. 第一个冲突:用户选择选项 1(优先采用当前分支的验证逻辑)
  2. 第二个类似的冲突:采用相同的推理方式(优先采用当前分支的验证方法)
  3. 提及:“保留当前分支的方法来解决(与您之前的选择一致)”

关键原则:

  • 在同一冲突解决会话中记住用户的偏好
  • 对类似冲突采用一致的处理模式
  • 说明处理的一致性:“沿用之前相同的处理模式……”
  • 如果新冲突与之前的冲突有明显差异,则再次询问

常见模式参考

如需详细的解决模式,请阅读:

  • references/patterns.md - 所有冲突类型的综合示例

快速查找模式:

  • 导入项:合并所有不重复的导入项,并按模块分组
  • 测试:保留所有测试(重复项除外),合并测试夹具
  • 生成文件:选择任一版本,并从源文件重新生成
  • 配置:合并所有键,发生冲突时选择更新或更安全的值
  • 代码:分析意图;如果改动互不冲突则合并,否则选择其一
  • Struct:包含两个分支中的所有字段
  • 文档:合并所有文档章节

特殊场景

冲突中的二进制文件

二进制文件无法合并。选择其中一个版本:

git checkout --ours path/to/binary    # keep our version
# or
git checkout --theirs path/to/binary  # keep their version
大规模重命名/重构冲突

如果一个分支重命名或重构了许多文件,而另一个分支修改了这些文件:

  1. 接受重命名/重构(结构性更改)
  2. 将修改应用到新结构中
  3. 使用 handle-deleted-modified.sh 中的备份来指导应用修改
子模块冲突
# Check submodule status
git submodule status

# Update to the correct commit
cd path/to/submodule
git checkout <desired-commit>
cd ../..
git add path/to/submodule

故障排除

“双方都新增”冲突(AA)

两个分支新增了同名但内容不同的文件:

  1. 检查两个版本
  2. 如果用途相同,则合并内容
  3. 如果用途不同,则重命名其中一个
仅空白字符冲突

如果冲突仅涉及空白字符差异:

git merge -Xignore-space-change <branch>
持续存在的冲突标记

如果验证显示仍有冲突标记,但你认为已经解决:

  1. 搜索准确的标记字符串:git grep -n "<<<<<<< HEAD"
  2. 某些标记可能位于字符串或注释中——也要解决这些标记
  3. 检查是否存在隐藏字符或编码问题
解决后测试失败
  1. 单独测试每个分支,确认测试通过
  2. 失败很可能是合并后的更改相互作用所致
  3. 调试相互作用问题,而不是单独的更改
  4. 更新代码,使两项更改能够协同工作

快速参考卡

冲突类型策略一句话说明模板
导入项全部合并、去重,并按模块分组“合并两条分支中的唯一导入项,并按模块分组”
测试全部保留,合并测试固件“纳入两条分支中的所有测试用例,并合并测试固件”
生成的文件根据源文件重新生成“根据源文件重新生成 [file],以纳入两条分支中的更改”
配置合并键,选择较新的值“合并所有配置键,并为 [key] 选择 [current/incoming] 值”
代码逻辑分析意图,若关注点互不冲突则合并“合并两项更改,因为它们处理的是不同的关注点”或“出于 [reason],选择 [current/incoming] 方案”
结构体纳入所有字段“在结构体定义中纳入两条分支中的所有字段”
文档合并所有章节“合并两条分支中的文档内容”
已删除-已修改备份、分析,并应用到新位置“文件移动或重命名后,将修改应用到新位置”
二进制文件选择一个版本“保留 [current/incoming] 版本的二进制文件”

请记住:

  • 始终为每项冲突解决方案提供一句话说明
  • 不确定时,向用户提供带编号的选项
  • 跟踪用户的决定,并将其一致地应用于类似冲突
  • 目标是在创建协调一致的合并结果时,保留两条分支的意图和功能

评论

支持 Markdown