Conflict Resolution¶
TaskRepo provides automatic conflict detection and resolution when syncing with git remotes.
Overview¶
When collaborating on tasks with others, conflicts can occur when: - Two people edit the same task simultaneously - Task is modified locally while remote has different changes - Sync occurs after prolonged offline work
TaskRepo's conflict resolution system automatically detects and intelligently resolves most conflicts, only prompting for manual intervention when necessary.
Conflict Detection¶
Before pulling changes, TaskRepo:
- Fetches remote changes without merging
- Compares local and remote task files
- Identifies conflicts where both versions differ
- Analyzes conflict type (simple field, list field, or description)
Resolution Strategies¶
TaskRepo offers four resolution strategies:
1. Auto (Default)¶
Command: tsk sync or tsk sync --conflict auto
Behavior: Smart automatic resolution when possible, interactive when necessary.
Automatic resolution rules: - Simple fields (status, priority, title, project, due): Uses value from newer task (based on modified timestamp) - List fields (assignees, tags, links): Creates union of both versions (no duplicates) - Timestamps (created, modified): Uses newer modified, preserves older created - Description conflicts: Prompts for manual resolution
Example:
Output:
🔄 Syncing repository: work
📥 Pulling changes...
⚠️ Conflict detected in task: Fix authentication bug
🤖 Auto-resolving conflict...
✓ Status: Using remote version (in-progress) - newer
✓ Assignees: Merged both versions (@alice, @bob, @charlie)
✓ Tags: Merged both versions (bug, security, urgent)
✓ Conflict resolved automatically
2. Local¶
Command: tsk sync --conflict local
Behavior: Always keep local version, discard remote changes.
Use when: - You know your local version is correct - Remote changes are outdated or incorrect - Quick sync without reviewing conflicts
Example:
Output:
🔄 Syncing repository: work
📥 Pulling changes...
⚠️ Conflict detected in task: Fix authentication bug
📌 Keeping local version (--conflict local)
Warning: Remote changes are lost. Use with caution.
3. Remote¶
Command: tsk sync --conflict remote
Behavior: Always keep remote version, discard local changes.
Use when: - Remote version is authoritative - Local changes were experimental or incorrect - Quick sync to match remote state
Example:
Output:
🔄 Syncing repository: work
📥 Pulling changes...
⚠️ Conflict detected in task: Fix authentication bug
🌐 Keeping remote version (--conflict remote)
Warning: Local changes are lost. Use with caution.
4. Interactive¶
Command: tsk sync --conflict interactive
Behavior: Always prompts for manual resolution, even for simple conflicts.
Use when: - You want full control over resolution - Need to review all conflicts manually - Working on critical tasks
Example:
Opens the interactive conflict resolver for every conflict.
Interactive Conflict Resolver¶
When automatic resolution isn't possible or --conflict interactive is used, TaskRepo opens a TUI for manual resolution.
Interface¶
┌─ Conflict Resolution ─────────────────────────────────────────┐
│ │
│ Task: Fix authentication bug │
│ UUID: a3f2e1d9-4b7c-4e3f-9a1b-2c3d4e5f6a7b │
│ │
├─ Local Version ──────────────┬─ Remote Version ────────────────┤
│ │ │
│ Status: pending │ Status: in-progress │
│ Priority: H │ Priority: H │
│ Assignees: @alice, @bob │ Assignees: @alice, @charlie │
│ Tags: bug, security │ Tags: bug, urgent │
│ Modified: 2025-10-29 14:30 │ Modified: 2025-10-29 15:45 │
│ │ │
│ Description: │ Description: │
│ JWT validation is broken. │ JWT validation is broken. │
│ │ Added fix in auth middleware. │
│ │ │
└──────────────────────────────┴─────────────────────────────────┘
Options:
[l] Keep local version
[r] Keep remote version
[n] Keep newer version (based on modified timestamp)
[m] Field-by-field merge
[e] Edit manually
[q] Skip this conflict
Resolution Options¶
Keep Local [l]¶
Preserves entire local task, discards remote changes.
Keep Remote [r]¶
Preserves entire remote task, discards local changes.
Keep Newer [n]¶
Automatically selects version with newer modified timestamp.
Field-by-Field Merge [m]¶
Opens submenu to select value for each conflicting field:
┌─ Field-by-Field Merge ───────────────────────────────────────┐
│ │
│ Status: │
│ [1] pending (local) │
│ [2] in-progress (remote) │
│ Selection: _ │
│ │
│ Assignees: │
│ [1] @alice, @bob (local) │
│ [2] @alice, @charlie (remote) │
│ [3] @alice, @bob, @charlie (union) │
│ Selection: _ │
│ │
│ Description: │
│ [1] JWT validation is broken. (local) │
│ [2] JWT validation is broken. │
│ Added fix in auth middleware. (remote) │
│ [3] Edit manually │
│ Selection: _ │
│ │
└───────────────────────────────────────────────────────────────┘
List fields: Automatically offers union option (all unique values combined)
Descriptions: Offers manual edit option if different
Edit Manually [e]¶
Opens task file in configured editor (default_editor or $EDITOR) for full manual control.
After editing: - File is validated for YAML syntax - Resolved task is saved - Continue to next conflict
Skip [q]¶
Skips this conflict, leaving file in conflicted state. You'll need to resolve manually later.
Smart Merge Rules¶
Simple Fields¶
Fields with single values: status, priority, title, project, due
Rule: Use value from task with newer modified timestamp
Example:
Local: status: pending, modified: 2025-10-29 14:30
Remote: status: in-progress, modified: 2025-10-29 15:45
Result: status: in-progress (remote is newer)
List Fields¶
Fields with multiple values: assignees, tags, links
Rule: Create union of both versions (no duplicates)
Example:
Local: assignees: [@alice, @bob]
Remote: assignees: [@alice, @charlie]
Result: assignees: [@alice, @bob, @charlie]
Advantages: - No data loss - Preserves contributions from both sides - Works well for collaborative editing
Timestamps¶
created and modified timestamps
Rules: - created: Use older value (original creation time) - modified: Use newer value (most recent edit)
Descriptions¶
Markdown content after YAML frontmatter
Rule: Requires manual resolution if different
Reason: Automatic merging of prose is unreliable and may produce nonsensical results.
Workflow Examples¶
Scenario 1: Simple Priority Change¶
Local: Changed priority from M to H Remote: Added assignee @charlie
Command:
Result: Auto-resolved - Priority: H (local, newer) - Assignees: Union of both (@alice, @bob, @charlie)
Scenario 2: Status Conflict¶
Local: Marked task as completed Remote: Marked task as in-progress
Command:
Result: Auto-resolved using newer timestamp - If local is newer: completed - If remote is newer: in-progress
Scenario 3: Description Conflict¶
Local: Updated description with new information Remote: Updated description with different information
Command:
Result: Interactive prompt - Opens conflict resolver - Choose: local, remote, or manual edit - Manually merge descriptions if needed
Scenario 4: Batch Sync with Conflicts¶
Multiple repositories with multiple conflicts
Command:
Result:
🔄 Syncing all repositories...
Repository: work
✓ Task 1: Auto-resolved (simple fields)
✓ Task 2: Auto-resolved (list fields merged)
⚠️ Task 3: Description conflict - prompting...
Repository: personal
✓ Task 4: Auto-resolved
✓ No conflicts
Summary: 3 auto-resolved, 1 manual, 0 failed
Best Practices¶
Sync Frequently¶
Sync often to minimize conflicts:
Use Descriptive Commit Messages¶
When syncing, TaskRepo commits changes with automatic messages. For important milestones, commit manually:
Review Auto-Resolutions¶
After auto-resolution, review changes:
Choose Strategy per Situation¶
- Daily sync:
tsk sync(auto) - Critical tasks:
tsk sync --conflict interactive - Quick updates:
tsk sync --conflict localor--conflict remote
Test with Dry Run¶
Before syncing important changes:
Handle Complex Conflicts Offline¶
For complex conflicts:
- Skip in resolver with [q]
- Edit file manually with full context
- Run sync again after resolution
Troubleshooting¶
Conflict Not Detected¶
Problem: Changes lost, no conflict detected
Cause: Timestamps not updated properly
Solution: Ensure you're using CLI commands (not direct file edits) or manually update modified timestamp
Merge Failed¶
Problem: Sync fails with merge error
Cause: Git merge conflict outside of task files
Solution:
Union Created Duplicates¶
Problem: List field has duplicate values
Cause: Different formatting (e.g., @alice vs @Alice)
Solution: TaskRepo normalizes GitHub handles, but check for typos:
Description Conflict Too Complex¶
Problem: Can't merge descriptions in resolver
Solution: Skip and use external diff tool:
# In conflict resolver: press [q] to skip
cd ~/tasks/tasks-work
git diff FETCH_HEAD -- tasks/task-{uuid}.md
# Use external merge tool
git mergetool tasks/task-{uuid}.md
Advanced: Manual Conflict Resolution¶
For full control, resolve git conflicts manually:
cd ~/tasks/tasks-work
# Fetch without merging
git fetch
# See conflicts
git diff HEAD..FETCH_HEAD
# Merge with manual resolution
git merge
# If conflicts occur
git status
vim tasks/task-{uuid}.md # Resolve manually
git add tasks/task-{uuid}.md
git commit
Implementation Details¶
Conflict resolution is implemented in: - src/taskrepo/utils/merge.py - Smart merge logic - src/taskrepo/tui/conflict_resolver.py - Interactive TUI - src/taskrepo/cli/commands/sync.py - CLI integration
Next Steps¶
- Git Sync - Git integration and collaboration
- Task Dependencies - Managing task dependencies
- Configuration - Configure conflict behavior