This commit is contained in:
Ewan Mellor
2015-05-02 20:04:24 -07:00
parent a6859bac22
commit 35abd26ba5
3 changed files with 178 additions and 0 deletions

View File

@ -3,6 +3,43 @@ git-diff-image
This is an extension to 'git diff' that provides support for diffing images.
Platforms
---------
Only OS X at the moment. Patches welcome!
Examples
--------
```
$ git diff
--- a/anImageThatHasChanged.jpg
+++ b/anImageThatHasChanged.jpg
@@ -1,5 +1,5 @@
ExifTool Version Number : 9.76
-File Size : 133 kB
+File Size : 54 kB
File Access Date/Time : 2015:05:02 20:01:21-07:00
File Type : JPEG
MIME Type : image/jpeg
$ git diff-image
# The same output as above, *and* a montage of the visual differences will be
# generated and opened in Preview.
```
Installation
------------
Install exiftool and ImageMagick. (The script will cope with these missing,
but it's not going to be very exciting without them.)
```
brew install exiftool imagemagick
```
Run the install script, which will configure your global git config for you.
Public domain dedication
------------------------

64
git_diff_image Executable file
View File

@ -0,0 +1,64 @@
#!/bin/bash
set -eu
set -o pipefail
name="$1"
f1="$2"
f2="$5"
name1="a/$name"
name2="b/$name"
if diff "$f1" "$f2" >/dev/null
then
exit 0
fi
exif() {
local b=$(basename "$1")
local d=$(mktemp -t "$b")
exiftool "$1" | grep -v "File Name" | \
grep -v "Directory" | \
grep -v "File Inode Change" | \
grep -v "File Modification Date/Time" | \
grep -v "File Permissions" \
>"$d"
echo "$d"
}
diff_clean_names() {
diff -u "$1" --label "$name1" "$2" --label "$name2" || true
}
if which -s exiftool
then
d1=$(exif "$f1")
d2=$(exif "$f2")
diff_clean_names "$d1" "$d2"
else
diff_clean_names "$f1" "$f2"
fi
if [ -z "${GIT_DIFF_IMAGE_ENABLED-}" ] || \
! which -s compare || \
! which -s montage
then
exit 0
fi
if compare "$f1" "$f2" /dev/null
then
exit 0
fi
bn=$(basename "$f1")
destfile=$(mktemp -t "$bn").png
compare "$f1" "$f2" png:- | \
montage -geometry +4+4 "$f1" - "$f2" png:- >"$destfile" 2>/dev/null || true
open "$destfile"

77
install.sh Executable file
View File

@ -0,0 +1,77 @@
#!/bin/bash
set -eu
set -o pipefail
cols=$(tput cols)
readlink_f() {
if [ $(uname) = 'Darwin' ]
then
local d=$(echo "${1%/*}")
local f=$(basename "$1")
(cd "$d" && echo "$(pwd -P)/$f")
else
readlink -f "$1"
fi
}
addattr() {
ext="$1"
if ! grep -qE "^\*.$ext diff=image\$" "$attributesfile"
then
if grep -qE "^\*.$ext" "$attributesfile"
then
fold -s -w$cols >&2 <<EOS
$attributesfile already has *.$ext configured, but not the way that this script requires.
If you want to use git-image-diff with $ext files, you must add a diff=image attribute yourself.
EOS
else
echo "+ echo '*.$ext diff=image' >>'$attributesfile'"
echo "*.$ext diff=image" >>"$attributesfile"
fi
fi
}
thisdir=$(dirname $(readlink_f "$0"))
thisdir_tilde="${thisdir/#$HOME/~}"
attributesfile_tilde=$(git config --global core.attributesfile || true)
attributesfile="${attributesfile_tilde/#\~/$HOME}"
if [ -z "$attributesfile" ]
then
attributesfile="$HOME/.gitattributes"
attributesfile_tilde="~/.gitattributes"
echo "+ git config --global core.attributesfile '$attributesfile_tilde'"
git config --global core.attributesfile "$attributesfile_tilde"
fi
if [ ! -f "$attributesfile" ]
then
if [ ! -e "$attributesfile" ]
then
echo "+ touch '$attributesfile'"
touch "$attributesfile"
else
echo "$attributesfile is not a regular file! I give up." >&2
exit 1
fi
fi
addattr gif
addattr jpeg
addattr jpg
addattr png
echo '+ git config --global alias.diff-image '"'"'!f() { GIT_DIFF_IMAGE_ENABLED=1 git diff "$@"; }; f'"'"
git config --global alias.diff-image '!f() { GIT_DIFF_IMAGE_ENABLED=1 git diff "$@"; }; f'
echo "+ git config --global diff.image.command '$thisdir_tilde/git_diff_image'"
git config --global diff.image.command "$thisdir_tilde/git_diff_image"