mpatch is a context-aware patching utility designed to handle the "messy" reality of modern development. Unlike standard patch or git apply, which fail if line numbers or context don't match exactly, mpatch uses fuzzy matching to locate changes based on the surrounding code structure.
It is specifically engineered to apply diffs generated by LLMs (ChatGPT, Gemini, Claude, Copilot), which often hallucinate line numbers or provide slightly outdated context.
You ask an AI to refactor a function. It gives you a diff. However, you modified a comment in that function 5 minutes ago.
Standard patch: Fails. The context lines don't match byte-for-byte.
mpatch: Succeeds. It sees the code structure is the same and applies the fix.
| Original File (Modified Locally) | AI-Generated Patch (Stale Context) | mpatch Result |
|---|---|---|
fn main() { |
fn main() { |
fn main() { |
- 🧠 Fuzzy Matching: Uses a similarity algorithm to find the best location for a patch when exact matches fail. It handles stale context, whitespace changes, and minor code drift.
- 🤖 Format Agnostic: Automatically detects and parses:
- Markdown code blocks (standard AI output).
- Raw Unified Diffs (
git diffoutput).
- ✨ Smart Indentation: Automatically adjusts the indentation of added lines to match the target file. Perfect for applying patches that were nested inside Markdown lists or have different tab/space styles.
- 🛡️ Secure: Built-in path traversal protection prevents malicious patches from writing outside the target directory (
../../etc/passwd). - ⚡ High Performance: Fuzzy searching is computationally expensive, so
mpatchparallelizes the search across all CPU cores usingrayon. - 🔍 Dry Run: Preview changes with
--dry-runbefore touching your filesystem.
We provide pre-compiled binaries for Windows, macOS, and Linux.
Using cargo-binstall (Fastest):
cargo binstall mpatchManual Download:
- Go to the Releases Page.
- Download the archive for your architecture (see table below).
- Extract and add to your
PATH.
| Platform | Architecture | Target | Notes |
|---|---|---|---|
| macOS | Universal | universal-apple-darwin |
Best for Mac. Runs natively on M1/M2/M3 & Intel. |
| x64 | x86_64-apple-darwin |
Older Intel Macs. | |
| ARM64 | aarch64-apple-darwin |
Apple Silicon (M1/M2/M3). | |
| Windows | x64 | x86_64-pc-windows-msvc |
Standard 64-bit Windows. |
| ARM64 | aarch64-pc-windows-msvc |
Surface Pro X, Parallels. | |
| Linux | x64 | x86_64-unknown-linux-gnu |
Ubuntu, Debian, Fedora, etc. |
| x64 (Static) | x86_64-unknown-linux-musl |
Alpine Linux, Docker containers. | |
| ARM64 | aarch64-unknown-linux-gnu |
Raspberry Pi 4/5, AWS Graviton. | |
| ARM64 (Static) | aarch64-unknown-linux-musl |
Alpine on ARM64. | |
| ARMv7 | armv7-unknown-linux-gnueabihf |
Older Raspberry Pi (2/3), IoT. | |
| ARMv7 (Static) | armv7-unknown-linux-musleabihf |
Static binaries for ARMv7. |
All release artifacts are signed with GPG. You can verify the integrity of the downloaded files using the .sig signature file and our public key (public.key), which is included in the release assets.
-
Import the public key:
gpg --import public.key
-
Verify the archive:
# Example for Linux x64 gpg --verify mpatch-x86_64-unknown-linux-gnu-v1.3.5.tar.gz.sig mpatch-x86_64-unknown-linux-gnu-v1.3.5.tar.gz
cargo install mpatchApply a patch file (Markdown, Diff, or Conflict markers) to a target directory.
mpatch changes.md ./srcSee exactly what will happen without modifying files.
mpatch --dry-run changes.md ./srcIf mpatch is matching the wrong place, increase the strictness (default is 0.7). If it's failing to find a match, lower it.
# Stricter (needs 90% similarity)
mpatch --fuzz-factor 0.9 changes.md ./src
# Disable fuzzy matching (exact match only)
mpatch --fuzz-factor 0.0 changes.md ./srcIf a patch fails, generate a comprehensive debug report (includes file states, logs, and diffs) to analyze why.
mpatch -vvvv changes.md ./src
# Generates: mpatch-debug-report-[timestamp].mdmpatch is designed to be the patching engine for AI coding agents and tools. It exposes a robust Rust API.
Add to Cargo.toml:
[dependencies]
mpatch = "1.3.5"Ideal for processing text in memory.
use mpatch::{patch_content_str, ApplyOptions};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let original_code = "fn main() { println!(\"Old\"); }";
// Input can be Markdown, Raw Diff, or Conflict Markers
let patch_text = r#"
```diff
--- a/main.rs
+++ b/main.rs
@@ -1 +1 @@
-fn main() { println!("Old"); }
+fn main() { println!("New"); }
```
"#;
let options = ApplyOptions::new(); // Default fuzz_factor: 0.7
let new_code = patch_content_str(patch_text, Some(original_code), &options)?;
assert_eq!(new_code, "fn main() { println!(\"New\"); }");
Ok(())
}Ideal for CLI tools applying multi-file patches.
use mpatch::{parse_auto, apply_patches_to_dir, ApplyOptions};
use std::path::Path;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let diff_content = include_str!("../tests/fixtures/changes.md");
// 1. Parse (automatically detects format)
let patches = parse_auto(diff_content)?;
// 2. Apply
let target_dir = Path::new("./src");
let options = ApplyOptions::new();
let results = apply_patches_to_dir(&patches, target_dir, options);
if results.all_succeeded() {
println!("All patches applied successfully!");
} else {
// Inspect specific failures
for (path, result) in results.hard_failures() {
eprintln!("Failed to process {}: {}", path.display(), result);
}
}
Ok(())
}mpatch automatically detects the format. You don't need to specify flags.
- Markdown Code Blocks:
Standard output from LLMs. Supports
```diff,```rust, or even generic blocks if they contain diff headers. - Unified Diffs:
Standard
git diffordiff -uoutput.
Fuzzy matching is an
- Heuristics:
mpatchfirst attempts exact matches and "whitespace-insensitive" exact matches before falling back to fuzzy search. - Anchoring: It scans for unique lines in the patch to narrow the search window.
- Parallelism: If a full scan is required, it uses Rayon to distribute the workload across all available CPU cores.
Benchmarks are available in benches/mpatch_bench.rs.
Contributions are welcome!
- Bug Reports: Please run
mpatch -vvvv ...to generate a debug report and attach it to your issue. - Development:
git clone https://github.com/romelium/mpatch.git cd mpatch cargo test
MIT License. See LICENSE for details.