threeway-merge-rs is a Rust library for string-based 3-way merging using Git's proven merge algorithms.
It uses libgit2/xdiff via safe FFI bindings, providing the same merge behavior as git merge-file but with a pure string API perfect for applications that need to merge text content programmatically.
- String-based API: Works with
&strinputs, no file I/O required - Git-compatible: 100% identical results to
git merge-file(576+ test combinations) - Memory safe: Safe Rust wrapper with proper FFI memory management
- Conflict detection: Automatic conflict counting and detailed output
- Zero runtime dependencies: C library compiled at build time
- Comprehensive testing: Multi-language scenarios with complex merge cases
Myers– Default, standard diffMinimal– Minimal changesPatience– Patience diff algorithmHistogram– Histogram-based diff
Minimal– Conservative mergingEager– Slightly more aggressiveZealous– Aggressive mergeZealousAlnum– Aggressive with alphanumeric heuristics
None– No automatic favorOurs– Prefer "ours" changesTheirs– Prefer "theirs" changesUnion– Combine changes when possible
Normal– Default 3-way mergeDiff3– Include base lines in conflictsZealousDiff3– Diff3 style with aggressive merging
- Customize marker labels and sizes (
<<<<<<<,=======,>>>>>>>)
Add to your Cargo.toml:
[dependencies]
threeway_merge = "0.1"use threeway_merge::{merge_strings, MergeOptions};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let base = "Hello world\nSecond line";
let ours = "Hello Rust world\nSecond line";
let theirs = "Hello beautiful world\nSecond line";
let result = merge_strings(base, ours, theirs, &MergeOptions::default())?;
println!("Conflicts: {}", result.conflicts);
println!("Result:\n{}", result.content);
Ok(())
}use threeway_merge::{
merge_strings, MergeOptions, DiffAlgorithm, MergeStyle, MergeFavor
};
let mut options = MergeOptions::default();
options.algorithm = DiffAlgorithm::Histogram;
options.style = MergeStyle::ZealousDiff3;
options.favor = Some(MergeFavor::Union);
options.base_label = Some("original".to_string());
options.ours_label = Some("mine".to_string());
options.theirs_label = Some("theirs".to_string());
options.marker_size = 10;
let result = merge_strings(base, ours, theirs, &options)?;This Rust code:
let result = merge_strings(base, ours, theirs, &options)?;Is equivalent to:
git merge-file --diff-algorithm histogram --zdiff3 \
-L "mine" ours.txt -L "original" base.txt -L "theirs" theirs.txt --stdoutThis library achieves 100% compatibility with git merge-file through comprehensive testing:
- 576+ test combinations across multiple scenarios
- 12+ complex merge scenarios including:
- Multi-language text (Korean, Japanese, French)
- Programming code (JavaScript, Rust, Python, SQL)
- Whitespace edge cases and deeply nested conflicts
- Literature excerpts and legal documents
# Run all tests
cargo test
# Run Git compatibility tests specifically
cargo test test_comprehensive_git_comparison
# Run with output visible
cargo test -- --nocapture# Validate publish artifacts without uploading
cargo xtask publish-dry
# Publish to crates.io
cargo xtask publish- Zero allocation for simple merges
- Memory efficient with automatic C memory cleanup
- Build-time compilation - no runtime dependencies
- Rust: 1.88.0 or later (uses 2024 edition)
- C compiler: For build-time compilation of xdiff library
- Git (optional): For running compatibility tests
- Rust – Systems programming language with safety and performance
- libgit2/xdiff – Standalone version of Git's xdiff library
- cc crate – Build-time C compilation
- Open Source Community: For the incredible tools and libraries
- Contributors: Everyone who improves
threeway-merge-rs - Davide Libenzi: Original author of xdiff
- libgit2 team: For maintaining the standalone xdiff version
This project is licensed under the MIT License.
This crate statically links the xdiff library (located in src/xdiff/), which is licensed under the GNU Lesser General Public License v2.1 or later (LGPL-2.1+).
The xdiff code is used unmodified from libgit2/xdiff.
Per the LGPL requirements, users can relink this crate against a modified version of xdiff:
- Modify the C source code in
src/xdiff/ - Rebuild the crate:
cargo build
All source code (including xdiff) is available in this repository, ensuring compliance with LGPL relinking requirements.
See src/xdiff/COPYING for the full LGPL license text.