a structural diff that understands syntax 🟥🟩
 
 
 
 
 
Go to file
Wilfred Hughes 3d0e80eb9a Add 'vendor/tree-sitter-elisp/' from commit '6fea410c8bab85639cf50041b5cbec3cbcb2de4c'
git-subtree-dir: vendor/tree-sitter-elisp
git-subtree-mainline: 70ef48dbb8
git-subtree-split: 6fea410c8b
2021-08-15 23:59:34 +07:00
.github/workflows Don't bother with clippy on CI for now 2021-03-07 14:10:44 +07:00
config Fix a parsing issue with -> in Rust 2021-07-31 01:25:16 +07:00
img Update screenshot 2021-07-24 18:07:32 +07:00
sample_files Add a sample file exercising contiguous item logic 2021-07-31 10:50:02 +07:00
src Simplify string literal pattern 2021-08-15 23:44:28 +07:00
vendor Add 'vendor/tree-sitter-elisp/' from commit '6fea410c8bab85639cf50041b5cbec3cbcb2de4c' 2021-08-15 23:59:34 +07:00
.gitignore Ignore local notes 2021-07-27 23:49:31 +07:00
CHANGELOG.md Roll version 2021-08-15 23:47:12 +07:00
Cargo.lock Use vendored tree-sitter-rust 2021-08-15 16:50:43 +07:00
Cargo.toml Use vendored tree-sitter-rust 2021-08-15 16:50:43 +07:00
LICENSE Add LICENSE file 2021-07-04 11:41:39 +07:00
README.md Be explicit about which languages are supported 2021-07-30 00:38:55 +07:00
build.rs Hook up vendored tree-sitter-css 2021-08-15 17:06:16 +07:00
text_diff_notes.md Add notes on LCS weaknesses 2021-03-21 13:34:01 +07:00

README.md

It's Difftastic!

Difftastic is an experimental structured diff tool that compares files based on their syntax.

screenshot

It currently supports the following languages:

  • Clojure
  • CSS
  • Emacs Lisp
  • Go
  • JavaScript
  • JSON
  • OCaml
  • Rust
  • Scheme

The parsing logic is based on matched delimiters, so difftastic tends to give best results on heavily parenthesised code (e.g. Lisps or JSON).

If a file has an unrecognised extension, difftastic uses a line-oriented diff.

How It Works

(1) Parsing.

Difftastic treats source code as a sequence of atoms or (possibly nested) lists.

Language syntax is defined in config/syntax.toml: you provide regular expressions for atoms (including comments), open delimiters, and close delimiters.

This is heavily inspired by Comby, which handles a large number of languages by using a similar approach.

(2) Diffing.

Difftastic treats diff calculations as a graph search problem. It finds the minimal diff using Dijkstra's algorithm.

This is based on the excellent Autochrome project.

(3) Printing.

Difftastic prints a side-by-side diff that fits the current terminal. It will try to align unchanged nodes (see screenshot above).

Known Problems

Crashes. The code is underdocumented, undertested, and unfinished.

Performance. Difftastic scales relatively poorly on files with a large number of changes, and can use a lot of memory. This might be solved by A* search.

Comments. Small changes can show big diffs.

Non-goals

Patch files. If you want to create a patch that you can later apply, use diff. Difftastic ignores whitespace, so its output is lossy. (AST patching is also a hard problem.)

Installation

You can install the latest tag of difftastic with Cargo:

$ cargo install difftastic

Difftastic is still under heavy development, so there's usually major bugfixes since the latest release. I currently recommend you check out the repository and compile directly:

$ cargo build --release

This will give you a binary at ./target/release/difftastic that you can put in a directory on your $PATH.

Dogfooding

Once you've compiled difftastic and it's on $PATH, you can try dogfooding.

To see the changes to the current git repo in difftastic, you can add the following to your .gitconfig and run git difftool.

[diff]
        tool = difftastic

[difftool]
        prompt = false

[difftool "difftastic"]
        cmd = difftastic "$LOCAL" "$REMOTE"

Alternatively, to run difftastic as the default diff engine for a git command:

$ CLICOLOR_FORCE=1 GIT_EXTERNAL_DIFF=difftastic git diff
$ CLICOLOR_FORCE=1 GIT_EXTERNAL_DIFF=difftastic git log -p --ext-diff

License

Difftastic is open source under the MIT license, see LICENSE for more details.

Files in sample_files/ are also under the MIT license unless stated otherwise in their header.

Further Reading

The wiki includes a thorough overview of alternative diffing techniques and tools.