Skip to content

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:

  1. Fetches remote changes without merging
  2. Compares local and remote task files
  3. Identifies conflicts where both versions differ
  4. 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:

tsk sync

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:

tsk sync --conflict local

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:

tsk sync --conflict remote

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:

tsk sync --conflict interactive

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.

✓ Conflict resolved: Kept local version

Keep Remote [r]

Preserves entire remote task, discards local changes.

✓ Conflict resolved: Kept remote version

Keep Newer [n]

Automatically selects version with newer modified timestamp.

✓ Conflict resolved: Kept newer version (remote, modified 2025-10-29 15:45)

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.

⚠️  Conflict skipped - manual resolution required

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:

tsk sync

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:

tsk sync

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:

tsk sync

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:

tsk sync --conflict auto

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:

# Start of work session
tsk sync

# End of work session
tsk sync --push

Use Descriptive Commit Messages

When syncing, TaskRepo commits changes with automatic messages. For important milestones, commit manually:

cd ~/tasks/tasks-work
git add .
git commit -m "Completed sprint planning tasks"
tsk sync --push

Review Auto-Resolutions

After auto-resolution, review changes:

tsk sync
tsk info 1  # Review resolved task

Choose Strategy per Situation

  • Daily sync: tsk sync (auto)
  • Critical tasks: tsk sync --conflict interactive
  • Quick updates: tsk sync --conflict local or --conflict remote

Test with Dry Run

Before syncing important changes:

# View what would be synced (git commands)
cd ~/tasks/tasks-work
git fetch
git status

Handle Complex Conflicts Offline

For complex conflicts:

  1. Skip in resolver with [q]
  2. Edit file manually with full context
  3. 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:

cd ~/tasks/tasks-work
git status
# Manually resolve git conflict
git add .
git commit

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:

tsk edit 1 --assignees @alice,@bob  # Clean up duplicates

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