blame-rs
Line-by-line authorship tracking for revisioned text using proven diff algorithms.
๐ Overview
blame-rs
is a Rust library for line-by-line authorship tracking in revisioned text.
Track which revision introduced each line in your documents with a flexible in-memory API.
โจ Features
- Generic metadata API: Attach any metadata type to revisions (commit hashes, authors, timestamps, etc.)
- Multiple diff algorithms: Support for Myers (default) and Patience algorithms via the
similar
crate - Forward tracking: Efficiently traces line origins from oldest to newest revision
- High performance:
- Zero-copy line tracking with
&str
references (no string allocations) - Shared metadata via
Rc<T>
(single clone per revision instead of per line) - Pre-allocated vectors (minimal heap reallocations)
- Zero-copy line tracking with
- Well tested: Comprehensive test suite with fixture-based scenarios
Supported Diff Algorithms
Myers (Default)
- Standard diff algorithm: Fast and reliable for most use cases
- O(ND) complexity: Efficient for typical text changes
- Widely used: Same algorithm used in many diff tools
Patience
- High-quality diffs: Produces more intuitive results for code
- Unique line matching: Better handling of code movement
- Ideal for: Source code with unique lines and structural changes
๐ Quick Start
Installation
Add to your Cargo.toml
:
[]
= "0.1.0"
Basic Usage
use ;
use Rc;
Output:
Line 0: line 1 (from Alice)
Line 1: line 2 (from Alice)
Line 2: line 3 (from Bob)
Advanced Configuration
use ;
let options = BlameOptions ;
let result = blame_with_options?;
for line in result.lines
๐ How It Works
The algorithm works by:
- Initialize: Starting with the first (oldest) revision, assigning all lines to that revision
- Iterate forward: Processing each consecutive revision pair
- Compute diff: Using the selected diff algorithm (Myers or Patience)
- Track origins: For each line in the newer revision:
- Equal โ Keep original metadata (unchanged line)
- Insert โ Assign current revision metadata (new line)
- Delete โ Remove from tracking (deleted line)
This forward-tracking approach ensures accurate line attribution even when lines are moved, modified, or deleted across multiple revisions.
Example Workflow
Rev 0 (Alice): Rev 1 (Bob): Rev 2 (Charlie):
fn main() { fn main() { fn main() {
println!("Hello"); println!("Hello"); println!("Rust!"); โ Changed
} println!("World"); println!("World");
} }
Result:
Line 0: fn main() { โ Alice (unchanged since Rev 0)
Line 1: println!("Rust!"); โ Charlie (changed in Rev 2)
Line 2: println!("World"); โ Bob (added in Rev 1)
Line 3: } โ Alice (unchanged since Rev 0)
๐ฆ Examples
See the examples/
directory for detailed usage:
basic_usage.rs
: Demonstrates blame with multiple revisions and formatted table outputdebug_example.rs
: Shows detailed blame output with revision content for debugging
Run examples with:
๐งช Testing & Quality
Comprehensive Test Suite
The library includes extensive testing with:
- Fixture-based tests: Multiple real-world scenarios in
tests/fixtures/
- Both algorithms tested: Every fixture runs with Myers and Patience
- Test scenarios include:
- Simple line additions
- Multiple revisions with incremental changes
- Line modifications and deletions
- Complex multi-revision histories
Running Tests
# Run all tests
# Run tests with detailed output
# Run specific fixture test
Test Output Example
================================================================================
Testing: multiple_revisions (Algorithm: Myers)
================================================================================
Revisions:
Rev 0: "a\nb"
Rev 1: "a\nb\nc"
Rev 2: "a\nb\nc\nd"
Blame Results:
Line Revision Content
------------------------------------------------------------
0 Rev 0 a
1 Rev 0 b
2 Rev 1 c
3 Rev 2 d
โ multiple_revisions (Myers) passed
๐ API Documentation
Generate and view the full API documentation:
Key types:
BlameRevision<'a, T>
: Represents a revision with content (&'a str
) and metadata (Rc<T>
)content: &'a str
- Zero-copy reference to revision contentmetadata: Rc<T>
- Shared reference-counted metadata (noT: Clone
required)
BlameLine<'a, T>
: A single line with its origin informationcontent: &'a str
- Zero-copy reference to the original linerevision_metadata: Rc<T>
- Shared reference to revision metadata
BlameResult<'a, T>
: Collection of blamed linesBlameOptions
: Configuration for the blame operationDiffAlgorithm
: Myers or Patience algorithm selection
Note: The library uses zero-copy string slices (&str
) and shared metadata (Rc<T>
) for optimal performance. Metadata types don't need to implement Clone
.
๐๏ธ Requirements
- Rust: 1.88.0 or later (uses 2024 edition)
- Dependencies:
similar
(2.7.0) โ Text diffing algorithmsthiserror
(2.0.17) โ Error handling
๐ Acknowledgments
Core Technologies
- Rust โ Systems programming language with safety and performance
- similar โ Powerful text diffing library by Armin Ronacher
Special Thanks
- Open Source Community: For the incredible tools and libraries
- Contributors: Everyone who improves
blame-rs
- similar maintainers: For providing excellent diff algorithms in Rust