Why don't git colours appear when using watch?
Solution 1:
git
uses a configuration value to determine whether to show coloured output or not.
For example:
git config --global color.ui auto
This sets the colour setting to auto
globally. In auto
mode, git will determine whether it's a real terminal before sending colour codes, as Oli suggested.
You can force this global value to always
, however a better idea may be to apply it to a particular command:
git -c color.status=always status -sb
Putting it all together:
watch --color git -c color.status=always status -sb
Solution 2:
The following statements are true:
-
watch
runs the command in a new shell,sh
. -
.bashrc
aliasesls
asls --color=auto
to enable colours. -
sh
doesn't inherit or usebash
aliases.
So when watch
runs ls
, it's not asking for colours, it's just running the plain old version. You can circumvent this but—as aditya points out—you also need to enable colours on watch
for it to process them properly.
A working example for ls
is:
watch --color -- ls --color=always
If you don't pass --color
to watch, you'll see a bunch of ugly colour codes inline.
ls --color
is interpreted as ls --color=always
.
ls --color=auto
does not print colour in watch. This suggests that it's inferring colour support from the terminal itself.
For more on the reason why, we can test if the watch shell thinks its a real terminal:
$ bash -c '[[ -t 1 ]] && echo "real terminal"'
real terminal
$ watch -- "bash -c '[[ -t 1 ]] && echo "real terminal"'"
# ... nothing.
I suspect that some applications are looking at that (or similar) to tell if they should turn on colours or not.