Gira Custom Git Merge Driver¶
Gira includes a custom Git merge driver that intelligently handles conflicts in JSON files, preventing data loss during concurrent modifications.
Overview¶
The merge driver provides semantic merging for: - Ticket files (handles status changes, field updates) - State files (manages counters and lists) - Configuration files - All other Gira JSON data
Features¶
Intelligent Conflict Resolution¶
-
Three-Way Merge: Compares base (ancestor), ours, and theirs versions to detect actual changes, not just differences.
-
Latest-Write-Wins Strategy: When the same field is modified in both branches, the version with the most recent
updated_at
timestamp is used. -
Field-Level Merging: Each field is merged independently, allowing non-conflicting changes to be combined.
-
Entity Validation: Verifies UUID/ID match before merging to prevent merging different entities.
-
State File Merging:
- Numeric counters take the maximum value
- Lists are merged with unique values
- Handles mixed data types intelligently
Conflict Tracking & Audit Trail¶
When conflicts are automatically resolved using the latest-write-wins strategy:
- A merge_notes
field is added to the merged file
- Each note includes timestamp, type ("auto-merge"), and affected fields
- Provides full transparency for automated conflict resolution
- Only added to files with an id
field (tickets, epics, etc.)
Installation¶
Automatic Setup¶
Run the setup script from your project root:
Manual Setup¶
- Configure Git to recognize the merge driver:
git config merge.gira-json.name "Gira JSON merge driver"
git config merge.gira-json.driver "python3 '.gira/scripts/merge-driver.py' %O %A %B"
git config merge.gira-json.recursive binary
- The
.gitattributes
file is already configured to use this driver for all Gira JSON files.
How It Works¶
During a merge, Git calls the merge driver with three versions of each conflicting file: - %O: The common ancestor (original) - %A: Our version (current branch) - %B: Their version (branch being merged)
The driver: 1. Parses all three JSON files 2. Identifies changes in each branch relative to the ancestor 3. Applies semantic rules to merge changes 4. Writes the merged result back to the working directory
Examples¶
Example 1: Field Conflict¶
If two users update the same ticket's priority: - User A: Changes priority from "medium" to "high" at 10:00 AM - User B: Changes priority from "medium" to "low" at 10:30 AM
Result: Priority will be "low" (User B's change is more recent)
Example 2: Status Movement¶
If two users move the same ticket: - User A: Moves from "todo" to "in_progress" - User B: Moves from "todo" to "review"
Result: The ticket location depends on which change has the latest timestamp.
Example 3: State File¶
If two users create tickets concurrently:
- User A: Creates tickets, next_ticket_id
becomes 105
- User B: Creates tickets, next_ticket_id
becomes 103
Result: next_ticket_id
will be 105 (maximum value)
Limitations¶
-
Binary Conflicts: The merge driver only handles JSON files. Binary files (images, etc.) still require manual resolution.
-
Structural Changes: Major structural changes to JSON schemas may require manual intervention.
-
Deletion Conflicts: If one branch deletes a ticket while another modifies it, manual resolution is needed.
Troubleshooting¶
Verify Installation¶
Check if the merge driver is configured:
Test the Merge Driver¶
Create a test conflict:
# Create two branches that modify the same ticket
git checkout -b test-branch-1
gira ticket update GCM-1 --priority high
git add . && git commit -m "Update priority to high"
git checkout main
git checkout -b test-branch-2
gira ticket update GCM-1 --priority low
git add . && git commit -m "Update priority to low"
# Merge to see the driver in action
git checkout test-branch-1
git merge test-branch-2
Debug Mode¶
To see detailed merge information, check the merge notes added to tickets after automatic conflict resolution.
Best Practices¶
-
Commit Frequently: Smaller, more frequent commits reduce the chance of conflicts.
-
Pull Before Major Changes: Update your local repository before starting significant work.
-
Use Descriptive Commit Messages: Include ticket IDs in commits for better tracking.
-
Review Merge Results: After automatic merges, review the changes to ensure the resolution makes sense for your workflow.