diffy

A Rust library for computing, parsing, and applying text diffs, patches, and three-way merges.

Library
Cargo
v0.5.1
122stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
52/100Fair
Development Activity44
Maintenance16
Community68
Maturity60
Momentum20

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture85
Code Quality90
Innovation78
Learning Curve65

diffy is a Rust crate for finding and manipulating differences between text and binary files, built around the Myers diff algorithm. It generates unified-format patches, applies patches to base files with GNU-patch-style fuzzy hunk placement, and performs three-way merges with diff3-style conflict markers. Recent releases added a patch_set module for streaming multi-file diffs such as git diff and git format-patch output, plus support for parsing and applying git binary patches.

The crate is no_std by default with alloc, keeping it usable in constrained environments, and gates I/O formatting, ANSI color output, and binary-patch application behind the std, color, and binary Cargo features respectively. It ships with a fuzz-tested parser, a compatibility test suite that replays real-world patches, and CI across stable, beta, nightly, and its pinned MSRV.

What You Get

  • Myers-algorithm diff engine for computing minimal edit scripts between texts or byte slices
  • Unified-format patch generation and parsing, with a Display impl and a colorized PatchFormatter
  • Patch application with GNU-patch-style fuzzy hunk repositioning when line numbers shift
  • Three-way merge with diff3-style conflict markers for reconciling divergent edits
  • A patch_set module for streaming multi-file unified diffs, including git-style renames, copies, and binary patches
  • A no_std + alloc core with opt-in std, color, and binary feature flags

Common Use Cases

  • Version control tooling - authors of Git-like or Mercurial-like tools use diffy to compute and apply diffs between file revisions.
  • Patch-based deployment and config sync - infrastructure tools generate a unified diff of a config file and apply it elsewhere with fuzzy hunk matching when contexts have drifted slightly.
  • Merge conflict resolution UIs - editors and merge tools use merge() to perform three-way merges and surface conflict markers to the user.
  • Parsing git patch output - CLI tools that consume git diff/git format-patch output use PatchSet::parse to iterate per-file changes, including renames and binary diffs.
  • Colorized diff output in terminal tools - CLI utilities use PatchFormatter::with_color() to render ANSI-colored unified diffs for developers.

Under The Hood

Architecture diffy is organized as a set of focused modules under src/ — diff/ (Myers algorithm plus a cleanup pass for readable hunk boundaries), patch/ (Hunk/Patch types, unified-format parsing and formatting), patch_set/ (a streaming parser for multi-file git-style diffs with rename/copy/binary detection), merge/ (three-way merge with diff3-style conflict markers), binary/ (git binary-patch base85 decoding and zlib-backed delta application), plus shared range.rs and utils.rs helpers. The public surface in lib.rs re-exports a small, deliberately narrow API (create_patch, apply, merge, and their _bytes variants) while keeping internal types private, so consumers interact with a stable facade even as the diff/merge internals evolve. Every layer works over generic slices via a SliceLike trait rather than assuming str, which is what lets the crate expose parallel str- and byte-oriented entry points without duplicating the algorithm. Because apply, merge, and patch_set all build on the same Patch/Hunk/HunkRange types from the patch module, a change to that core representation would ripple through every consumer-facing operation.

Tech Stack The crate targets Rust edition 2024 with MSRV 1.85.0 and is no_std by default, using extern crate alloc for Vec/String/Cow. Its only mandatory runtime dependency is hashbrown (used with the default-hasher feature for the diff classifier’s hash map); anstyle is pulled in only under the optional color feature for ANSI-styled patch output, and zlib-rs (with the c-allocator feature) is pulled in only under the optional binary feature for git binary-delta decompression. Dev-dependencies are rayon, for parallelizing the replay test suite, and snapbox with its dir feature for snapshot-testing directory fixtures. There’s no build script or external tooling beyond Cargo itself; CI runs the test matrix across stable, beta, nightly, and the pinned MSRV, with separate workflows for fuzzing, a full replay-corpus run, a dependency and license audit, and rustdoc publishing.

Code Quality Testing is layered: each core module (diff, patch, patch_set, merge) ships its own cfg(test) tests.rs alongside the implementation, the public API in lib.rs is documented almost entirely through runnable doctests, and a top-level replay test suite replays real-world patches against the implementation, split into a lighter default CI run versus a full corpus run. A dedicated fuzz directory with its own Cargo.toml and fuzz targets supplies fuzz coverage on the parser and applier. Error handling is explicit and typed — ApplyError, ParsePatchError, and the patch_set error type all implement core::error::Error rather than surfacing strings or panics — and a clippy lint block plus warnings against std-in-place-of-core/alloc enforce the no_std discipline at compile time. Coverage of the diff/patch/merge core is extensive; the binary/base85 delta path is covered mainly via a fixture-driven compatibility suite.

API Design The public API favors small, composable functions over a large object model: create_patch/apply/merge (and their _bytes twins) are free functions returning owned Patch/String values, while DiffOptions and MergeOptions expose a builder-style configuration surface only when defaults aren’t enough. Getting started requires almost no boilerplate — the doctests in lib.rs are literally two-line usage examples — and the crate’s feature flags (std, color, binary) are additive, so the default no_std, no-color, text-only build stays minimal while opt-in features unlock formatting, ANSI color, and git binary-patch support without changing call sites. The trade-off is that PatchSet’s streaming-iterator API and its FileOperation enum require a bit more upfront reading than the top-level functions, though this mirrors patterns familiar to anyone who has used git’s own diff machinery.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search