Git is an awesome version control tool. Currently I use it exclusively for projects where I get to decide the VCS. I mostly use the command line interface and gitk and since I’m quite fluent with these the work flow is most of the time quite quick.
One of the occasions where gitk doesn’t really do well is showing differences in image files. For example, when there is a .png image checked in to the git repository and it changes gitk (nor bare git) tells nothing about what changed visually in the image.
Since git is quite configurable and extendable I wanted to search for a way to amend it somehow in order to really see how the images in my git repositories have changed – visually.
First off course I searched from the net what kind of solutions others might have for this problem. I got some ideas but not really a satisfying complete solution.
From  I found the tip of using .gitattributes for specifying how to handle diffs for images differently from other file types. From  I got encouragement to use ImageMagick for showing the diffs. I have used ImageMagick before for many things so it wasn’t a new tool for me. I might have used it anyway.
These propositions were still lacking in my opinion so I needed to improve them.
My solution for image diffs in git
Here’s a step-by-step guide how I currently do my image diffs with git.
Telling git that images are images
First I needed to tell git that it should handle image files specifically. This was achieved with a .gitattributes file. Since in my opinion images are images regardless of the project or git repository I’m using, I did this globally. It’s possible to do this per project too if you so wish.
First I specified a global git setting for a global .gitattributes file:
[~]$ git config --global core.attributesfile '~/.gitattributes'
Then in the file specified above I added some specifications that tell git that some file name extensions should be considered as image files:
[~]$ cat .gitattributes *.gif diff=image *.jpg diff=image *.png diff=image
More file name extensions can be off course added as needed.
Telling git how to show diffs for images
After the previous step git knows what are image files but it still wouldn’t show their diffs any differently from other binary files. That needed to be specified next.
First I added another global setting to git that specifies a command that is used for diffs of files of type “image”:
[~]$ git config --global diff.image.command '~/bin/git-imgdiff'
The script specified in that setting needs to off course exist. Here’s the contents of the script that I currently have:
[~]$ cat ~/bin/git-imgdiff #!/bin/sh compare $2 $1 png:- | montage -geometry +4+4 $2 - $1 png:- | display -title "$1" -
All of the commands used in the script (compare, montage and display) belong to the ImageMagick suite.
And that’s it so far. There’s off course a lot of place for improvement but this is my current solution.
Here’s an example screenshot what the result of all this might look like:
The starting point of the diff is on the left, the end point of the diff is on the right and the differences of the images are in the middle. The changes in the image are shown with a bright red colour.