Difftastic is a structural diff tool that understands syntax. It supports over 20 programming languages and when it works, it's fantastic.
Difftastic is open source software (MIT license) and available on GitHub.
This copy of the manual describes version 0.30.0. The changelog records which features and bug fixes are in each version.
Difftastic detects the language, parses the code, and then compares the syntax trees. Let's look at an example.
// old.rs let ts_lang = guess(path, guess_src).map(tsp::from_language);
// new.rs let ts_lang = language_override .or_else(|| guess(path, guess_src)) .map(tsp::from_language);
$ difft old.rs new.rs 1 1 let ts_lang = language_override . 2 .or_else(|| guess(path, guess_src)) . 3 .map(tsp::from_language);
Notice how difftastic recognises that
.map is unchanged, even though
it's now on a new line with whitespace.
A line-oriented diff does a much worse job here.
$ diff -u old.rs new.rs @@ -1 +1,3 @@ -let ts_lang = guess(path, guess_src).map(tsp::from_language); +let ts_lang = language_override + .or_else(|| guess(path, guess_src)) + .map(tsp::from_language);
Some textual diff tools also highlight word changes (e.g. GitHub or
--word-diff). They still don't understand the code
though. Difftastic will always find matched delimiters: you can see
or_else has been highlighted.
If input files are not in a format that difftastic understands, it uses a conventional line-oriented text diff with word highlighting.
Difftastic will also use textual diffing when given extremely large inputs.