a structural diff that understands syntax 🟥🟩
 
 
 
 
 
Go to file
Wilfred Hughes 206e9be4b2 Ensure apply_color_by_line doesn't discard newlines 2019-01-22 00:35:19 +07:00
sample_files Tweak colour to avoid confusion with the red shown during diffing 2018-12-31 11:25:15 +07:00
src Ensure apply_color_by_line doesn't discard newlines 2019-01-22 00:35:19 +07:00
.gitignore Initial proof of concept 2018-12-29 15:29:42 +07:00
.travis.yml Adding a basic Travis configuration 2019-01-14 01:15:50 +07:00
Cargo.lock Pad to the terminal width if the files are narrower 2018-12-31 17:53:07 +07:00
Cargo.toml Pad to the terminal width if the files are narrower 2018-12-31 17:53:07 +07:00
README.md Expand related projects 2018-12-30 01:36:48 +07:00
after.js Adding a modified list to a sample file 2019-01-16 09:42:16 +07:00
before.js Adding a modified list to a sample file 2019-01-16 09:42:16 +07:00

README.md

Difftastic

A language-aware word-level diff.

Other Diff Techniques

There are a bunch of other ways of diffing text files. I summarise them here, along with example invocations.

Myers' diff algorithm

This is the default diff algorithm in GNU diff and git diff. It finds the longest common subsequence (LCS) and is used on a line-by-line basis.

There's a great introduction here and the original paper is An O(ND) Difference Algorithm and Its Variations, Myers 1986.

# Modern diff supports colour, but see also
# https://www.colordiff.org/
$ diff --color=always -u css_before.css css_after.css

Note that GNU diff originally used the Hunt-McIlroy algorithm).

Patience Diff

Myer's diff has a problem with sliders:

 if (!$smtp_server) {
+       $smtp_server = $repo->config('sendemail.smtpserver');
+}
+if (!$smtp_server) {
        foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {
                if (-x $_) {
                        $smtp_server = $_;

Instead of:

+if (!$smtp_server) {
+       $smtp_server = $repo->config('sendemail.smtpserver');
+}
 if (!$smtp_server) {
        foreach (qw( /usr/sbin/sendmail /usr/lib/sendmail )) {
                if (-x $_) {

Git has a --indent-heuristic that was added to reduce the likelihood of making a bad choice. There's a corpus of test files where the ideal diff has been chosen by a human, to test different heuristics.

The patience diff algorithm is an LCS algorithm that aims to do a better job with sliders. It produces great results by doing more work.

# Original behaviour
$ git diff --no-indent-heuristic --no-index css_before.css css_after.css
# As of git 2.11, this heuristic is enabled by default.
$ git diff --indent-heuristic --no-index css_before.css css_after.css
# Patience algorithm does a better a job in this example.
$ git diff --patience --no-index css_before.css css_after.css

Histogram Diff

Git 1.7.7+ also has a histogram algorithm, which aims to produce better results than Myers' algorithm but without the slowdown of the patience algorithm.

# Inferior to patience on this example file.
$ git diff --histogram --no-index css_before.css css_after.css