@@ -19,12 +19,15 @@ A Git-aware conflict resolver for **JSON-first structured data**.
1919## Features
2020
2121- ⚡ ** Primary focus on JSON** (first-class support)
22- - 🔄 ** YAML, XML, TOML** supported via conversion
23- - 🧩 ** Rule-based strategies** (per path/pattern)
24- - 🗂️ Handles small configs to ** huge repos** (optimizations built-in)
25- - 🔌 ** Pluggable matcher** abstraction (picomatch, micromatch supported out of the box with peerDependency)
26- - 🛠️ Configurable trade-offs for ** speed vs. memory**
27- - 🗃️ ** Planned** : extend configuration to use ** different strategies per file** (ideas and edge cases welcome!)
22+ - 🔄 ** YAML, XML, TOML, JSON5** supported via conversion
23+ - 🧩 ** Rule-based strategies** with path/pattern matching
24+ - 📁 ** Multiple file parallel processing** with include/exclude patterns
25+ - 🔌 ** Pluggable matcher** abstraction (picomatch, micromatch, or custom)
26+ - 🛠️ ** CLI and programmatic API** support
27+ - 📝 ** Conflict sidecar files** for unresolved conflicts
28+ - 🔄 ** Backup and restore** functionality
29+ - 📊 ** Configurable logging** (memory or file-based)
30+ - 🔀 ** Git merge driver** support for seamless Git integration
2831
2932## Installation
3033
@@ -46,6 +49,24 @@ yarn add git-json-resolver
4649
4750## Quick Start
4851
52+ ### CLI Usage
53+
54+ ``` bash
55+ # Initialize config file
56+ npx git-json-resolver --init
57+
58+ # Run with default config
59+ npx git-json-resolver
60+
61+ # Run with options
62+ npx git-json-resolver --include " **/*.json" --debug --sidecar
63+
64+ # Restore from backups
65+ npx git-json-resolver --restore .merge-backups
66+ ```
67+
68+ ### Git Integration
69+
4970Add a custom merge driver to your Git config:
5071
5172``` bash
@@ -57,73 +78,172 @@ Update `.gitattributes` to use it for JSON files:
5778
5879``` gitattributes
5980*.json merge=json-resolver
81+ *.yaml merge=json-resolver
82+ *.yml merge=json-resolver
83+ *.toml merge=json-resolver
84+ *.xml merge=json-resolver
6085```
6186
62- ## Example Config
87+ ** How it works:**
88+
89+ - Git automatically calls the merge driver during conflicts
90+ - Uses same configuration and strategies as CLI mode
91+ - Supports 3-way merge (ours, base, theirs)
92+ - Returns proper exit codes (0 = success, 1 = conflicts)
93+
94+ ## Configuration
95+
96+ ### Programmatic API
6397
6498``` ts
6599import { resolveConflicts } from " git-json-resolver" ;
66100
67- const result = resolveConflicts ({
68- filePath: " package.json" ,
69- rules: [
70- { pattern: " dependencies.*" , strategy: " ours" },
71- { pattern: " version" , strategy: " theirs" , important: true },
72- { pattern: " scripts.build" , strategy: " manual" },
73- ],
74- matcher: " picomatch" , // default
75- optimize: {
76- cacheMatchers: true ,
77- streamMode: false , // set true for very large repos
101+ await resolveConflicts ({
102+ defaultStrategy: [" merge" , " ours" ],
103+ rules: {
104+ " dependencies.*" : [" ours" ],
105+ version: [" theirs!" ], // ! marks as important
106+ " scripts.build" : [" skip" ],
78107 },
108+ include: [" **/*.json" , " **/*.yaml" ],
109+ exclude: [" **/node_modules/**" ],
110+ matcher: " picomatch" ,
111+ debug: true ,
112+ writeConflictSidecar: true ,
113+ backupDir: " .merge-backups" ,
79114});
80115```
81116
82- ### Upcoming: File-Specific Strategies
83-
84- We are exploring the ability to define ** per-file strategy sets** in config, e.g.:
85-
86- ``` ts
87- rulesByFile : {
88- " package.json" : { version: [" theirs" ], dependencies: [" ours" ] },
89- " *.config.json" : { " *" : [" merge" ] },
90- },
117+ ### Config File (` git-json-resolver.config.js ` )
118+
119+ ``` js
120+ module .exports = {
121+ defaultStrategy: [" merge" , " ours" ],
122+ rules: {
123+ // Exact path matching
124+ " package.json" : {
125+ version: [" theirs!" ],
126+ dependencies: [" ours" ],
127+ },
128+ // Pattern matching
129+ " *.config.json" : {
130+ " *" : [" merge" ],
131+ },
132+ },
133+ // Alternative: byStrategy format
134+ byStrategy: {
135+ ours: [" dependencies.*" , " devDependencies.*" ],
136+ " theirs!" : [" version" , " name" ],
137+ },
138+ include: [" **/*.json" , " **/*.yaml" , " **/*.yml" ],
139+ exclude: [" **/node_modules/**" , " **/dist/**" ],
140+ matcher: " picomatch" ,
141+ debug: false ,
142+ writeConflictSidecar: false ,
143+ loggerConfig: {
144+ mode: " memory" , // or "stream"
145+ logDir: " logs" ,
146+ levels: {
147+ stdout: [" warn" , " error" ],
148+ file: [" info" , " warn" , " error" ],
149+ },
150+ },
151+ };
91152```
92153
93- This raises interesting questions/edge cases:
94-
95- - How to merge file-level vs. global rules?
96- - Should ` include/exclude ` still apply if a file is explicitly listed?
97- - Should conflicting rules between file + global fall back to default strategy or error?
98-
99- We welcome ideas & edge cases here!
100-
101154## Supported Strategies
102155
156+ - ** merge** → deep merge objects/arrays where possible
103157- ** ours** → take current branch value
104158- ** theirs** → take incoming branch value
105- - ** manual** → mark for human resolution
106- - ** drop** → remove the key entirely
107- - ** custom** → user-defined resolver function
159+ - ** base** → revert to common ancestor
160+ - ** skip** → leave unresolved (creates conflict entry)
161+ - ** drop** → remove the field entirely
162+ - ** non-empty** → prefer non-empty value (ours > theirs > base)
163+ - ** update** → update with theirs if field exists in ours
164+ - ** concat** → concatenate arrays from both sides
165+ - ** unique** → merge arrays and remove duplicates
166+ - ** custom** → user-defined resolver functions
167+
168+ ### Strategy Priority
169+
170+ - Strategies marked with ` ! ` (important) are applied first
171+ - Multiple strategies can be specified as fallbacks
172+ - Custom strategies can be defined via ` customStrategies ` config
108173
109174## Supported Formats
110175
111176- ** JSON** (native)
112- - ** YAML, XML, TOML** → converted to JSON → resolved → converted back
177+ - ** JSON5** → via ` json5 ` peer dependency
178+ - ** YAML** → via ` yaml ` peer dependency
179+ - ** TOML** → via ` smol-toml ` peer dependency
180+ - ** XML** → via ` fast-xml-parser ` peer dependency
181+
182+ All non-JSON formats are converted to JSON → resolved → converted back to original format.
183+
184+ ## CLI Options
185+
186+ ``` bash
187+ # File patterns
188+ --include " **/*.json,**/*.yaml" # Comma-separated patterns
189+ --exclude " **/node_modules/**" # Exclusion patterns
190+
191+ # Matcher selection
192+ --matcher picomatch # picomatch, micromatch, or custom
193+
194+ # Debug and logging
195+ --debug # Enable verbose logging
196+ --sidecar # Write conflict sidecar files
197+
198+ # Utilities
199+ --init # Create starter config file
200+ --restore .merge-backups # Restore from backup directory
201+ ```
113202
114- ## Performance & Optimization
203+ ## Architecture
115204
116- - ** Matcher caching** for repeated patterns
117- - ** Streaming mode** for very large repos (low memory footprint)
118- - Trade-offs are configurable via ` optimize ` field
205+ - ** Modular design** : Separate concerns (parsing, merging, serialization)
206+ - ** Reusable utilities** : Common merge logic extracted for maintainability
207+ - ** Optimized bundle** : Constants over enums for better minification
208+ - ** Comprehensive testing** : Full test coverage with vitest
209+ - ** Type-safe** : Full TypeScript support with proper type inference
210+
211+ ## Advanced Features
212+
213+ ### Pattern Matching
214+
215+ - ** Exact paths** : ` "package.json" ` , ` "src.config.database.host" `
216+ - ** Field matching** : ` "[version]" ` → matches any ` version ` field
217+ - ** Glob patterns** : ` "dependencies.*" ` , ` "**.config.**" `
218+ - ** Wildcards** : ` "*.json" ` , ` "src/**/*.config.js" `
219+
220+ ### Custom Strategies
221+
222+ ``` ts
223+ import { StrategyStatus } from " git-json-resolver" ;
224+
225+ const config = {
226+ customStrategies: {
227+ " semantic-version" : ({ ours , theirs }) => {
228+ // Custom logic for semantic version resolution
229+ if (isNewerVersion (theirs , ours )) {
230+ return { status: StrategyStatus .OK , value: theirs };
231+ }
232+ return { status: StrategyStatus .CONTINUE };
233+ },
234+ },
235+ rules: {
236+ version: [" semantic-version" , " theirs" ],
237+ },
238+ };
239+ ```
119240
120- ## Roadmap
241+ ### Logging & Debugging
121242
122- - [ ] Richer strategies via plugins (e.g., semantic version resolver)
123- - [ ] CLI UX improvements
124- - [ ] Pluggable format converters customizations
125- - [ ] VSCode integration for previewing merge resolutions
126- - [ ] ** Per-file strategies support** (current RFC)
243+ - ** Memory mode** : Fast, in-memory logging
244+ - ** Stream mode** : File-based logging for large operations
245+ - ** Per-file logs** : Separate log files for each processed file
246+ - ** Debug mode** : Detailed conflict information and strategy traces
127247
128248## Contributing
129249
0 commit comments