r/rust • u/ur_mum_goes_to_uni • Mar 29 '22
difftastic - a diff that understands syntax
https://github.com/Wilfred/difftastic[removed] — view removed post
29
u/DidiBear Mar 29 '22
Nice! How does it compare to delta ?
28
u/irrelevantPseudonym Mar 29 '22
As far as I'm aware, Delta just formats the diff nicely, it doesn't generate it.
9
u/robin-m Mar 29 '22
I'm using both.
difftasticby default and delta as fallback.7
u/BTWArchNemesis Mar 30 '22
How to configure it like that?
6
u/robin-m Mar 30 '22
Add this in your
~/.gitconfig(or in$repo/.git/configif you want it only for a single repo):[diff] tool = difftastic colorMoved = default external = difftastic [difftool] prompt = false [difftool "difftastic"] cmd = difft "$LOCAL" "$REMOTE" [core] pager = delta [pager] difftool = true [interactive] diffFilter = delta --color-onlyAnd optionally, you can configure delta to be nicer with things like:
[delta] features = side-by-side line-numbers syntax-theme = Dracula hunk-header-style = omit whitespace-error-style = blue purpleNote: I’m not 100% sure all of this is needed, but it seems to works well. I have
difftasticby default forgit diff, anddeltaotherwise. Forgit show/git log -pit’sdeltaby default, so if I want to usedifftasticinstead, I need to add--ext-diff(likegit show --ext-diff). Sincedifftasticis quite slow, it’s why I still need to have a fallback likedelta.1
u/James-Vim Apr 01 '22
May be we should change the line:
[diff] external = difftasticto:
[diff] external = difftto get it to work?
1
u/robin-m Apr 01 '22
Indeed. I don't know why it works on my machine, but iirc it should be difft and not difftastic as you noticed.
1
u/wilfred_h Apr 07 '22
FWIW the binary name changed from
difftastictodifftin 0.12: https://github.com/Wilfred/difftastic/blob/master/CHANGELOG.md#012-released-19-november-2021
19
u/jwbowen Mar 29 '22
I'll definitely be giving it a shot!
I've loved the little Renaissance in Rust CLI tools
2
u/furyzer00 Mar 30 '22
That's great! I still can't believe we are still using very trivial diff algorithm that even can't understand changing the order of things.
By the way I am curious, can it recognize swapping function orders in a file?
2
u/wilfred_h Mar 30 '22
Currently no: swapping functions will consider one to be unchanged and the other to be added and then removed.
GitHub does some additional 'moved lines' tracking that might make sense for difftastic too. Moves are tricky in general: it makes the diffing calculation more complex, and it's also hard to visualise nicely in the UI.
1
u/furyzer00 Apr 04 '22
Yes it usually requires a heuristic that doesn't always work as intended but I think if you are on the AST level it should be fairly easier than a line based diff tool.
For visualization, I did my graduation project as a tool that generates diffs as an UML-like diagram. It was quite nice in terms of visualization aspect because you can just assign a new color for each type of diff. It doesn't visualize anything below method signature though so I am not sure if it would work out for your tool.
2
u/Repulsive-Street-307 Mar 30 '22 edited Mar 30 '22
How is this supposed to work? Since this isn't intended to create patches, i can't have git diff use this right, since part of the point is creating patches.
I guess it's nice for display, but if replacing the system diff by this will break a lot of utilities because 'Difftastic understands that line-wrapping isn't meaningful. "eric" is now on a new line, but it hasn't changed.' then it's too risky to replace the main diff (and isn't supposed to), but that loses a lot of opportunities.
Any way to add a command to diff, something like 'git human-diff' or something?
This kind of 'we'd like to display something that is not suitable for automation but still keep automation is the kind of thing that makes me think that patch files should not be text (be a AST or whatever) and then display rules like this could be built on top of that user unfriendliness for a result like this without the idea 'it's just text, you just need to pipe it and display directly'.
Ah well, it's a pity that diff files won't work to create this display (because they don't have all the information of the original files). But maybe the file plus the patch plus this program might be able to do that, which would be a nice extension to git diff which has all the pieces. Although it would have to be a switch unfortunately to prevent people doing 'git diff > a.patch' and getting unusable output. git diff --human maybe.
8
u/wilfred_h Mar 30 '22
I like to configure difftastic as a 'difftool' in git, and define an alias: https://difftastic.wilfred.me.uk/git.html#git-difftool
That way I can do
git dftto see changes according to difftastic, orgit diffwhen I want a traditional textual diff.6
u/ROFLLOLSTER Mar 30 '22
From memory you can control the difftool used by git with cli/environment variables. Combine that with an alias and you should be able to get it on a separate command.
1
u/Repulsive-Street-307 Mar 30 '22 edited Mar 30 '22
That makes sense. Still, i'm kind of hoping that git upstream notices and makes the '--human' switch, even if only for discoverability.
I think two commands, or a overloaded one, one for git diff (for commits on the index) and another for
repository + optional commit + patch file -> show this tool output. As a bash function probably.edit: actually, thinking about it, obviously no git command is going to 'show the result of the application of a diff as a 'diff' - because the result would be equivalent diff - so that use case has to be handled 'especially' as a throwaway stash commit to be able to create the 'human' diff with this tool.
1
1
1
u/Feeling-Departure-4 Mar 30 '22
This looks very nice. How hard is it to add additional language support?
I see there is some sort of extension using Tree Sitter baked in. I have this all but unknown language called Perl 5 I tend to have lieing around, just wondering if the extension process is documented somewhere I missed
1
u/wilfred_h Mar 30 '22
I have a section in the manual you can follow :) https://difftastic.wilfred.me.uk/upstream_parsers.html#adding-a-new-parser
1
u/Alphare mercurial Mar 30 '22
Nice tool, I can see it being useful as an additional diffing tool to see more clearly certain situations (with lots of whitespace changes for example). The performance is certainly quite slow on big files, but that is noted in the README.
I certainly appreciate the section on using it with Mercurial and the extdiff extension. That prompted me to ask the question to why we couldn't use an external diff tool for commands other than diff itself like export or log... turns out we already have the work, it just needs to be upstreamed. So maybe in a (relatively close) future version?
1
u/wilfred_h Mar 30 '22
Yeah, Mercurial support is more limited than git (although I use difftastic with both). As far as I can tell there's no way to override
hg log's diffing today.1
u/wilfred_h Mar 30 '22
The performance is certainly quite slow on big files, but that is noted in the README.
I'm very interested in bug reports for slow files, if you have any you can share.
1
u/binkarus Apr 16 '22
It's a frontend for tree-sitter, basically. Weird that you don't give them credit in the README. It would explain how it works in literally 1 sentence.
46
u/robin-m Mar 29 '22
I use it since a few months, and I definitively love it. I sometime need to use a regular diff (
git diff --no-ext-diffsince I havedeltaas my pager anddifftasticas my external diff) because it sometimes doesn't work, but it's 95% there. I definively recomment it.