I'm using difftastic for better visualisation of my diffs in my terminal. Which means my config is
git config --global diff.external difft
However, when the output is not a tty, I'd rather have git use it's internal diff tool (e.g. the same as doing git diff --no-ext-diff
but without me having to type that). So basically
$ git diff # please use difft
# git diff | cat # please use no external diff tool
However, I'm struggling with that because I cannot find a way to bubble up this information to my diff tool. Let's say I have some pseudo diff tool that actually just shows content of argv, first line of argc and check if its stdout is a tty:
#!/usr/bin/env ruby
require "io/console"
require "logger"
require "pp"
f = File.open("mygitdiff.log", "a")
f.puts("\n---- #{Time.now}")
PP.pp(ARGV, f)
PP.pp(gets, f)
f.puts("STDOUT.tty? #{STDOUT.tty?}")
This script prints the same log whether I am piping or not:
---- 2022-08-02 18:57:30 +0200
["bin/new",
"/var/folders/v5/1p20ylgn0db5621r8wtdg5v80000gn/T//37FrIz_new",
"c2a6c5aafc3485755f774cb3efcae4a2819a777f",
"100755",
"bin/new",
"0000000000000000000000000000000000000000",
"100755"]
"#!/usr/bin/env ruby\n"
STDOUT.tty? false
---- 2022-08-02 18:57:34 +0200
["bin/new",
"/var/folders/v5/1p20ylgn0db5621r8wtdg5v80000gn/T//jaEmlN_new",
"c2a6c5aafc3485755f774cb3efcae4a2819a777f",
"100755",
"bin/new",
"0000000000000000000000000000000000000000",
"100755"]
"#!/usr/bin/env ruby\n"
STDOUT.tty? false
As you can see there is no major difference there. Do you have any other idea how to achieve that goal?
Also note that the first line of argv, I don't understand at all what it means
A solution is to create a new git
bin file, and put it in your path somewhere before the original git path (for me /usr/bin
). The wrapper will decide whether an external diff tool should be used depending on the stdout state:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
if (isatty(fileno(stdout)) && isatty(fileno(stderr))) {
setenv("GIT_EXTERNAL_DIFF", "difft", 1);
}
execvp("/usr/bin/git", argv);
}