Since Git1.6.3, you can use the git difftool script: see my answer below.
May be this article will help you. Here are the best parts:
There are two different ways to specify an external diff tool.
The first is the method you used, by setting the GIT_EXTERNAL_DIFF variable. However, the variable is supposed to point to the full path of the executable. Moreover, the executable specified by GIT_EXTERNAL_DIFF will be called with a fixed set of 7 arguments:
path old-file old-hex old-mode new-file new-hex new-mode
As most diff tools will require a different order (and only some) of the arguments, you will most likely have to specify a wrapper script instead, which in turn calls the real diff tool.
The second method, which I prefer, is to configure the external diff tool via "git
config". Here is what I did:
1) Create a wrapper script "git-diff-wrapper.sh" which contains something like
-->8-(snip)--
#!/bin/sh
# diff is called by git with 7 parameters:
# path old-file old-hex old-mode new-file new-hex new-mode
"<path_to_diff_executable>" "$2" "$5" | cat
--8<-(snap)--
As you can see, only the second ("old-file") and fifth ("new-file") arguments will be
passed to the diff tool.
2) Type
$ git config --global diff.external <path_to_wrapper_script>
at the command prompt, replacing with the path to "git-diff-wrapper.sh", so your ~/.gitconfig contains
-->8-(snip)--
[diff]
external = <path_to_wrapper_script>
--8<-(snap)--
Be sure to use the correct syntax to specify the paths to the wrapper script and diff
tool, i.e. use forward slashed instead of backslashes. In my case, I have
[diff]
external = \"c:/Documents and Settings/sschuber/git-diff-wrapper.sh\"
in .gitconfig and
"d:/Program Files/Beyond Compare 3/BCompare.exe" "$2" "$5" | cat
in the wrapper script. Mind the trailing "cat"!
(I suppose the '| cat
' is needed only for some programs which may not return a proper or consistent return status. You might want to try without the trailing cat if your diff tool has explicit return status)
(Diomidis Spinellis adds in the comments:
The cat
command is required, because diff(1)
, by default exits with an error code if the files differ.
Git expects the external diff program to exit with an error code only if an actual error occurred, e.g. if it run out of memory.
By piping the output of git
to cat
the non-zero error code is masked.
More efficiently, the program could just run exit
with and argument of 0.)
That (the article quoted above) is the theory for external tool defined through config file (not through environment variable).
In practice (still for config file definition of external tool), you can refer to:
To fix the OutOfMemory error, you should do something like this:
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 8;
Bitmap preview_bitmap = BitmapFactory.decodeStream(is, null, options);
This inSampleSize
option reduces memory consumption.
Here's a complete method. First it reads image size without decoding the content itself. Then it finds the best inSampleSize
value, it should be a power of 2, and finally the image is decoded.
// Decodes image and scales it to reduce memory consumption
private Bitmap decodeFile(File f) {
try {
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(new FileInputStream(f), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE=70;
// Find the correct scale value. It should be the power of 2.
int scale = 1;
while(o.outWidth / scale / 2 >= REQUIRED_SIZE &&
o.outHeight / scale / 2 >= REQUIRED_SIZE) {
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
return BitmapFactory.decodeStream(new FileInputStream(f), null, o2);
} catch (FileNotFoundException e) {}
return null;
}
Best Answer
My own favorites are these two:
The only difference between the 2 commands above: the first one shows the visual difference between the two images as a PNG file, the second one as a PDF.
The resulting diff file displays all pixels which are different in red color. The ones which are unchanged appear white.
Short and sweet.
Note, your images need not be the same type. You can even mix JPEG, TIFF, PNG -- under one condition: the images should be of the same size (image dimension in pixels). The output format is determined by the output filename's extension.
Should you, for some reason, need a higher resolution than the default one (72 dpi) -- then just add an appropriate
-density
parameter:Illustrated examples
Here are a few illustrations of results for variations of the above command. Note: the two files compared were even PDF files, so it works with these too (as long as they are 1-pagers)!
Left: Image with text Center: Original image Right: Differences (=text) in red pixels.![Red difference pixels only; identical pixels are white](https://i.stack.imgur.com/8ZUXl.png)
This is the same command I suggested earlier above.
Left: Image with text Center: Original image Right: Differences in 'seagreen' pixels.![Seagreen difference pixels only; identical pixels are white](https://i.stack.imgur.com/Udvz4.png)
This command adds a parameter to make the difference pixels 'seagreen' instead of the default red.
Left: Image with text Center: Original image Right: Blue diffs (but w. some context background)
l
This command removes the
-compose src
part -- the result is the default behavior ofcompare
which keeps as a lightened background the first one of the 2 diffed images. (This time with added parameter to make the diff pixels appear in blue.)