Why does a pipe remove the branch names from git log?
Asked Answered
R

2

14

when I run

> git log --oneline

I get output that looks like this

abcdef0 (head, branch, origin/branch) comment
0987654 different comment
1234567 (different-branch, origin/branch) third comment

But as soon as I pipe the output to anything (e.g. > git log --oneline | cat), the branch names are gone

abcdef0 comment
0987654 different comment
1234567 third comment

This means I can't grep, or add line numbers, or anything like that.

(It's also missing the colors and less style behavior, but I don't care about that either way today)

Is this something I can re-enable via a command-line parameter?

Rittenhouse answered 20/6, 2019 at 23:15 Comment(0)
H
8

For start, I too had noticed the lack of colors after a pipe to bash, but what you describe about decorations (branch and tag names) disappearing is odd. Let's adress them separately.

Adressing the branch names (decorations) themselves

--decorate

is the flag for that, for a one-shot use.

For the permanent effect, you can set it in your config

log.decorate true

And for a more specific need, note you can use it in a pretty format, with the placeholder %d, for example :

git log -10 --pretty=format:"%C(yellow)%h %C(reset)%aN %ar %C(red)%d %C(reset)%s"

for a result that looks like this

enter image description here

About colors

No, I don't know how / why it breaks when it's passed to bash, I'll let more advanced users answer that part. (and as I said, on a personal note I'm very glad you asked this question because I'm eager to know that too - Edit : thanks torek! :-) )

Harty answered 20/6, 2019 at 23:16 Comment(2)
Explanation is that running git without telling it if you want colors or not, git will try to see if you are running on a virtual terminal (like a console) and if output is not being piped or something... if that's the case, it will resort to use color.Inverter
I think there's also the --color/--no-color option.Inverter
S
7

The git log command is what Git calls porcelain. This means it is meant to be used by actual humans, as opposed to other Git commands like git rev-parse and git for-each-ref that are mostly or entirely meant for computer programs to run.

Porcelain commands are usually configurable, and often do things like color or paginate their output. This is true for git log as well. Several of the controls for this are git config entries:

color.ui = auto
log.decorate = auto

This auto setting, which is the default—you can change it to always or never—tells Git: When the command writes its output to a terminal, do it, but when it does not (like when it writes to a pipe as in git branch | grep ...), don't do it.

The log.decorate option controls the (master) decorations. Whether particular text is colored, and if so, with which colors, is controlled by a rather complicated maze of options that merely starts with color.ui.

Setting color.ui to always will break naive scripts that run porcelain commands in pipelines and expect color.ui to be set to its default auto. None of Git's own scripts are naive like this, but you may be using your own extensions, or ones obtained from people who didn't think about the issue, so be careful when overriding these defaults.

(By the way, be careful about the = in settings. These are required inside .git/config and git -c color.ui=true log, for instance, but forbidden in git config log.decorate auto. It's a crazy mishmash of historical artifacts and coding whatever was expedient at the time.)

Saraband answered 21/6, 2019 at 0:24 Comment(3)
I tried git config --global color.ui always but to no effect (my test has been to send my usual log alias (with colors set in pretty format) through a simple grep). What did I miss? :-/Harty
@RomainValeri: not sure, but note that git log doesn't use color that much on its own: it colors commit hash IDs and some --decorate items, and leaves much of the rest to the diff code where color.diff will override color.ui. git log itself takes a --color=<when> as well and the documentation says: "By default, colors are shown only when enabled for log output (by color.diff, color.ui, or --color, and respecting the auto settings of the former if we are going to a terminal). ..."Saraband
Meanwhile the git config documentation implies that color.diff would override color.ui when some program queries, e.g., git config --get-colorbool color.diff. I have my color.diff set to auto but git config --get-colorbool color.diff prints nothing for me. There's also color.pager and I'm not sure if this overrides other settings, although I don't set it myself.Saraband

© 2022 - 2024 — McMap. All rights reserved.