From e164856ab8d80c13b082a283b4c73b6fb31968f6 Mon Sep 17 00:00:00 2001 From: Sebastian Thiel Date: Mon, 19 Sep 2022 21:55:48 +0800 Subject: [PATCH] feat: forward line-diffing capabilities curtesy of the `similar` crate. (#470) This is a first and maybe the last step towards providing diffing functionality, and it seems like the right choice to keep this in similar and contribute there as needed. All algorithms are well described and thus shouldn't be git-specific per-se, and `similar` is the best the community has to offer. --- Cargo.lock | 4 ++++ git-diff/Cargo.toml | 1 + git-diff/src/lib.rs | 3 +++ git-diff/src/lines.rs | 26 ++++++++++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 git-diff/src/lines.rs diff --git a/Cargo.lock b/Cargo.lock index a89a532b3a..51e4d975db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1262,6 +1262,7 @@ dependencies = [ "git-odb", "git-testtools", "git-traverse", + "similar", "thiserror", ] @@ -2899,6 +2900,9 @@ name = "similar" version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803" +dependencies = [ + "bstr 0.2.17", +] [[package]] name = "slab" diff --git a/git-diff/Cargo.toml b/git-diff/Cargo.toml index 23853efe91..a42c308e58 100644 --- a/git-diff/Cargo.toml +++ b/git-diff/Cargo.toml @@ -15,6 +15,7 @@ doctest = false git-hash = { version = "^0.9.9", path = "../git-hash" } git-object = { version = "^0.20.3", path = "../git-object" } thiserror = "1.0.32" +similar = { version = "2.2.0", features = ["bytes"] } [dev-dependencies] git-odb = { path = "../git-odb" } diff --git a/git-diff/src/lib.rs b/git-diff/src/lib.rs index e279b442a1..e1f1d292be 100644 --- a/git-diff/src/lib.rs +++ b/git-diff/src/lib.rs @@ -4,3 +4,6 @@ /// pub mod tree; + +/// +pub mod lines; diff --git a/git-diff/src/lines.rs b/git-diff/src/lines.rs new file mode 100644 index 0000000000..ebb58ddb62 --- /dev/null +++ b/git-diff/src/lines.rs @@ -0,0 +1,26 @@ +use git_object::bstr::BStr; +use similar::TextDiff; + +/// The crate powering file diffs. +pub use similar; +pub use similar::Algorithm; + +/// Provide an iterator over the changes needed to turn `old` into `new` with `algorithm`. +/// +/// See [the `similar` crate documentation][similar::TextDiffConfig::diff_lines()] for information on how to use the iterator. +pub fn with<'old, 'new, 'bufs>( + old: &'old BStr, + new: &'new BStr, + algorithm: Algorithm, +) -> TextDiff<'old, 'new, 'bufs, [u8]> { + similar::TextDiffConfig::default() + .algorithm(algorithm) + .diff_lines(old.as_ref(), new.as_ref()) +} + +/// Provide an iterator over the changes needed to turn `old` into `new` with Myers algorithm, the default for `git`. +/// +/// See [the `similar` crate documentation][similar::TextDiffConfig::diff_lines()] for information on how to use the iterator. +pub fn myers<'old, 'new, 'bufs>(old: &'old BStr, new: &'new BStr) -> TextDiff<'old, 'new, 'bufs, [u8]> { + with(old, new, Algorithm::Myers) +}