Implement Conflict Resolution (Automated + Manual)
Implement conflict resolution that combines automated field-level merging for simple cases with git-based tools for complex description conflicts.
Overview
When both local and remote issues have been modified (BOTH_MODIFIED state), the system should:
- Auto-resolve when possible (different fields modified)
- Use git merge tools for description conflicts
- Provide CLI for listing and resolving conflicts
Phase 1: Automated Field-Level Resolution
When conflicts occur but different fields were modified, auto-merge both changes:
- Detect which specific fields changed locally vs remotely
-
Auto-merge when no field overlap (e.g., local changed
title, remote changedlabels) - Handle comments as append-only (merge new comments from both sides)
- Report what was auto-merged in output
Examples of auto-resolvable conflicts:
- Local: title changed | Remote: labels changed → merge both
- Local: description changed | Remote: milestone changed → merge both
- Local: added comment | Remote: added different comment → append both
Phase 2: Git-Based Description Resolution
When both local and remote modified the description:
-
Use
git merge-filefor three-way merge (local, original, remote) -
Insert Git conflict markers (
<<<<<<<,=======,>>>>>>>) when merge fails - Allow user to resolve in their preferred editor
- Optionally launch vimdiff/mergetool for interactive resolution
-
Respect user's
git config merge.toolsetting
Phase 3: CLI Commands
-
gl-issue-sync conflicts list- list all conflicted issues from conflicts.json (renamed fromconflicts) -
gl-issue-sync conflicts show <IID>- show detailed conflict information with file locations and field comparisons -
gl-issue-sync conflicts resolve <IID>- mark issue as resolved (updates original snapshot to remote) -
Show which fields conflict and which can be auto-resolved (via
conflicts showcommand) - During push, record conflicts to conflicts.json when BOTH_MODIFIED detected
Acceptance Criteria
- Simple field conflicts are auto-resolved without user intervention
- Description conflicts use git merge-file for three-way merge
-
CLI shows clear conflict details (which fields, auto-resolvable vs manual) - via
conflicts listandconflicts show - User's git mergetool config is respected (planned in #169 - interactive merge tool)
- Conflict state persisted after failed push
-
conflicts resolve <IID>enables subsequent push
Critical: Post-Resolution Snapshot Management
Problem: After resolving a conflict, if user runs push, the system would detect:
- Local (resolved) ≠ Original
- Remote ≠ Original
- Result: BOTH_MODIFIED again → infinite conflict loop!
Solution: After resolution, update original snapshot to match REMOTE, not local.
Before resolution:
Local: [resolved content]
Original: [old version]
Remote: [their changes]
→ BOTH_MODIFIED
After `conflicts resolve <IID>` (original = remote):
Local: [resolved content]
Original: [their changes] ← updated to match remote
Remote: [their changes]
→ LOCAL_MODIFIED → push proceeds normally
Conflict State Tracking
After a (partially) failed push, we need to remember which issues had conflicts:
-
Store conflict state in
.issues/.sync/conflicts.json - Record IID, conflict type, timestamp, and which fields conflicted
-
conflictscommand reads this file to list unresolved conflicts -
conflicts resolve <IID>removes the issue from conflicts.json after updating snapshot - Clear conflict state for an issue after successful push
Example conflicts.json:
{
"42": {
"detected_at": "2026-01-07T10:30:00Z",
"fields": ["description", "title"],
"auto_resolvable": false
},
"55": {
"detected_at": "2026-01-07T10:30:00Z",
"fields": ["labels"],
"auto_resolvable": true
}
}
References
- PRD Section 4.10: Conflict Resolution (REQ-CNF-001 through REQ-CNF-005)
- PRD Section 8.14:
gl-issue-sync conflictscommand - PRD Section 12.5: Manual resolution via vimdiff or git mergetool
- Milestone 4: Kanban and Conflicts
Edited by Emma