Executables can Introspect their Output Destination

Usually, when I type:

$ git log --oneline --graph

I see something like this:

git log output with ref names and color output

But recently, I typed:

$ git log --oneline --graph | head -15

And I saw this:

git log output without ref names and uncolored output

I was confused why the output differed; to my knowledge, head did not alter its input at all. And indeed, it doesn’t - but git log does alter its output depending on whether or not the output is a TTY. It does this via isatty(3).

Since git v2.13, git log gets a --decorate=auto default. The documentation for git log --decorate reads:

If auto is specified, then if the output is going to a terminal, the ref names are shown as if short were given, otherwise no ref names are shown. The default option is short.

Since head is not a TTY, the ref names & color codes are omitted from the output of git log.

You can see the call to isatty(3) in the git log source.