
本文详解如何在基于 git2go 的协作编辑器中正确处理 Git 合并冲突:关键在于区分“冲突检测”与“冲突解决后提交”,需显式调用 StateCleanup() 并避免重复 merge 操作,确保索引状态同步、工作区变更被真正提交。
本文详解如何在基于 git2go 的协作编辑器中正确处理 git 合并冲突:关键在于区分“冲突检测”与“冲突解决后提交”,需显式调用 `statecleanup()` 并避免重复 merge 操作,确保索引状态同步、工作区变更被真正提交。
在使用 git2go 实现多人实时协作编辑(如 Live-Editor)时,一个常见陷阱是:当发生合并冲突后,用户手动编辑并保存文件,但后续再次执行 add/commit/push 流程时,系统仍报告相同冲突——看似“冲突未解决”,实则是 Git 状态管理缺失所致。
根本原因在于:git2go 的 repo.Merge() 仅执行三路合并并写入索引(含冲突标记),但不会自动提交;若用户修改冲突标记后的文件内容,却未将这些修改重新加入索引并提交,则下一次 MergeAnalysis 仍会检测到旧的冲突状态(因索引未更新、HEAD 未前进),导致循环报错。
✅ 正确流程应严格分为三个阶段:
- 冲突检测阶段:调用 repo.MergeAnalysis() + repo.Merge(),检查 index.HasConflicts();若为 true,立即终止流程,将冲突内容(含 >>>>>> 标记)返回前端供用户编辑;
- 冲突解决与提交阶段:用户编辑后,必须执行完整 Git 提交流程——index.AddAll() → index.Write() → index.WriteTree() → repo.CreateCommit(...),且该提交必须是普通单亲提交(非 merge commit);
- 后续同步阶段:仅在无冲突时,才执行 Fetch + MergeAnalysis + Merge + CreateCommit(merge) 流程,并以 repo.StateCleanup() 清理合并状态(如 .git/MERGE_HEAD、索引锁等)。
以下是关键逻辑的精简实现(已去除日志与错误处理,聚焦主干):
// Step 1: Detect conflicts during pull-merge
err := repo.Merge([]*git.AnnotatedCommit{annotatedCommit}, nil, nil)
if err != nil {
return err // e.g., fast-forward impossible
}
index, _ := repo.Index()
if index.HasConflicts() {
index.Write() // persist conflict markers to disk
return errors.New("conflicts_detected")
}
// Step 2: If no conflicts → auto-commit merge
treeId, _ := index.WriteTree()
tree, _ := repo.LookupTree(treeId)
localCommit, _ := repo.LookupCommit(currentCommit)
remoteCommit, _ := repo.LookupCommit(remoteBranch.Target())
repo.CreateCommit("HEAD", sig, sig, "Merge branch 'origin/master'", tree, localCommit, remoteCommit)
// Step 3: ALWAYS clean up merge state after successful merge commit
repo.StateCleanup()
⚠️ 特别注意以下三点:
- index.HasConflicts() 必须在 repo.Merge() 后立即检查,不可延迟到 AddAll 之后——否则可能掩盖真实冲突状态;
- 用户解决冲突后,必须重新 AddAll + Write 索引,再 WriteTree 创建新树对象,否则 CreateCommit 将基于旧冲突索引生成无效提交;
- repo.StateCleanup() 不可省略:它清除 .git/MERGE_HEAD、.git/index.lock 等临时状态,防止下次 MergeAnalysis 错误复用残留元数据。
此外,建议在每次操作前校验仓库状态:
if repo.State() == git.RepositoryStateMerge {
// 阻止在未完成合并时执行 add/commit
return errors.New("repository in merge state, please resolve conflicts first")
}
通过以上结构化流程,即可完全复现命令行 git merge + git add + git commit 的语义,确保 git2go 在协作场景中行为可靠、状态一致。











