Clojure-aware source code diffing

I’m looking for a tool or plugin which provides a more Clojure-aware source code diffing function. What do I mean by this?

Traditionally, a source code diff works on a text file and shows you difference at the level of the line/character within a line. While this is certainly better than no diffing algorithm, I more useful solution would be something which performs a diff between two files which also understands the syntax of the language being diff’ed.

In the case of Clojure/Script, it would be a fairly straightforward matter of reading each file into the reader, and then performing a diff between the two resulting lists, and then producing a report of the changes. For example, it can produce statements such as

  • added new function func1
  • removed function func2
  • move function func3
  • updated function func4
  • … and so on

You could even configure it to give more details on updates.

My question is, is anyone aware of such a tool or plugin which exists out there?

I remember seeing discussion about this a few years ago but to my knowledge nothing has been built that does what you ask.

This article might be useful if you decide to build it yourself:

I’d love to have a tool like you describe.

Thanks @Arthur_Boyer, this is very useful. I too would love to have this, I think it’ll save a lot of time by cutting out a lot of monotonous and error-prone work. As and when I get the time I’ll really look into what is involved.

In the mean time if anyone has any suggestions or recommendations for libraries that might be useful, please post them.

The good news is that people have been making lisp-oriented diffs for a long time, and Clojure is just the lastest in a long line of lisps.

The bad news is that I had trouble finding much to link for you, but I confess I didn’t dig that deep. Some of the ancient lisp diffs were made before “google” was a thing!

Here’s a taste to get you started if you want to dig deeper. It may not do clojure, it may not do much of interest at all, or maybe it’s a place to start. I would suggest searching for Common Lisp diff tools.

I too started with a similar approach, a straight diff between two forms, then I realized that that wasn’t quite sufficient. It will be necessary as part of the solution, but I also need to take into account top-level vars, how they are def’ined (via def, defn etc.), as well as Clojure-specific oddities like reader macros, reader condtionals and so on. It’s a lot more involved than it first seems, but with enough experimentation and learning more about the various compilation pipelines, I may be able to put something useful together.

I’ve been curious about this too and found git’s word diffs to be reasonably helpful. They’re not perfect, but can help highlight things that are harder to spot in line-based diffs:

git diff --word-diff=color

produces diffs like

image

Hey that’s really neat, I didn’t know you could do that! I always assumed there was just the standard default diff and you couldn’t change it.

I’m reasonably certain that with at least Clojure you can run something which can even determine that you’ve moved a function from one namespace to another, provided you keep the same name. It won’t be perfect either, but there is a large amount of code analysis that can be done to make the process of documenting commits a lot less manual. It should be like this with most languages, but given Clojure’s homoiconicity and the fact that it has the tools to parse/analyze itself, it should be relatively easier than with most other languages.

This is the tool I remembered seeing:

http://fazzone.github.io/autochrome.html

There’s an open issue regarding git integration:

2 Likes

Now that actually looks like the sort of thing I was looking for, thanks for digging up. I haven’t downloaded it yet but from what I’ve read it sounds like what I was after.
:+1: