JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 79
  • Score
    100M100P100Q79655F
  • License MPL-2.0

A rules-based JSON conflict resolver that parses Git conflict markers, reconstructs ours/theirs, and merges with deterministic strategies — beyond line-based merges.

Package Exports

  • json-conflict-resolver

Readme

Git Json Resolver

test Maintainability codecov Version Downloads npm bundle size

A Git-aware conflict resolver for JSON-first structured data.

Why?

  • Git merge conflicts in structured files (JSON, YAML, XML, TOML) are painful.
  • Manual resolution is error-prone, time-consuming, and breaks CI/CD pipelines.
  • git-json-resolver automates conflict handling with configurable strategies.
  • Non-JSON formats are internally normalized to JSON → resolved → converted back.

Features

  • Primary focus on JSON (first-class support)
  • 🔄 YAML, XML, TOML supported via conversion
  • 🧩 Rule-based strategies (per path/pattern)
  • 🗂️ Handles small configs to huge repos (optimizations built-in)
  • 🔌 Pluggable matcher abstraction (picomatch, micromatch supported out of the box with peerDependency)
  • 🛠️ Configurable trade-offs for speed vs. memory
  • 🗃️ Planned: extend configuration to use different strategies per file (ideas and edge cases welcome!)

Installation

pnpm add git-json-resolver

or

npm install git-json-resolver

or

yarn add git-json-resolver

Quick Start

Add a custom merge driver to your Git config:

git config merge.json-resolver.name "Custom JSON merge driver"
git config merge.json-resolver.driver "npx git-json-resolver %A %O %B"

Update .gitattributes to use it for JSON files:

*.json merge=json-resolver

Example Config

import { resolveConflicts } from "git-json-resolver";

const result = resolveConflicts({
  filePath: "package.json",
  rules: [
    { pattern: "dependencies.*", strategy: "ours" },
    { pattern: "version", strategy: "theirs", important: true },
    { pattern: "scripts.build", strategy: "manual" },
  ],
  matcher: "picomatch", // default
  optimize: {
    cacheMatchers: true,
    streamMode: false, // set true for very large repos
  },
});

Upcoming: File-Specific Strategies

We are exploring the ability to define per-file strategy sets in config, e.g.:

rulesByFile: {
  "package.json": { version: ["theirs"], dependencies: ["ours"] },
  "*.config.json": { "*": ["merge"] },
},

This raises interesting questions/edge cases:

  • How to merge file-level vs. global rules?
  • Should include/exclude still apply if a file is explicitly listed?
  • Should conflicting rules between file + global fall back to default strategy or error?

We welcome ideas & edge cases here!

Supported Strategies

  • ours → take current branch value
  • theirs → take incoming branch value
  • manual → mark for human resolution
  • drop → remove the key entirely
  • custom → user-defined resolver function

Supported Formats

  • JSON (native)
  • YAML, XML, TOML → converted to JSON → resolved → converted back

Performance & Optimization

  • Matcher caching for repeated patterns
  • Streaming mode for very large repos (low memory footprint)
  • Trade-offs are configurable via optimize field

Roadmap

  • Richer strategies via plugins (e.g., semantic version resolver)
  • CLI UX improvements
  • Pluggable format converters customizations
  • VSCode integration for previewing merge resolutions
  • Per-file strategies support (current RFC)

Contributing

Contributions welcome 🙌

  • Fork, branch, PR — with tests (vitest required)
  • Docs live in libDocs/ (tutorials, guides, deep dives)
  • API reference generated into docs/ via TypeDoc

License

This library is licensed under the MPL-2.0 open-source license.

Please enroll in our courses or sponsor our work.


with 💖 by Mayank Kumar Chaudhari