Git 颜色配置 —— color.ui、槽位、pager、--color=always
git 为 diff、status、log、branch、grep 与交互选择器发出 ANSI / VT 转义码 —— 每个子命令都有自己的开关,每个输出元素都有可单独着色的命名槽位,而默认的 less pager 会剥离 SGR,除非你告诉它别这么做。下方七段复制即用片段覆盖完整配置地图,从全局 color.ui 开关到权威的 LESS=FRX pager 参数,再到 git log --color=always | less -R 管道配方。
配置片段
color.ui —— 全局开关(git 1.8.4 起默认)
从 git 1.8.4(2013 年 8 月)起 color.ui 的默认值是 auto —— stdout 为 TTY 时发出 SGR,被管道时剥离。更早版本默认 false;遗留的 .gitconfig 文件常无端固定为 false。可选值:auto(仅 TTY)、always / true(始终发出 —— 在通过 less -R 等渲染器管道时有用)、never / false(永不发出)。color.ui 是唯一一次影响所有子命令的开关;按命令的键(color.diff 等)会覆盖它。
# Inspect current value (auto = sane default).
git config --get color.ui
# The sane default — emit colour on TTY, strip on pipe:
git config --global color.ui auto
# Force colour through pipes (for piping into less -R, see snippet 6):
git config --global color.ui always
# Disable globally (e.g. dumb terminal, log scraping, or accessibility):
git config --global color.ui never
# or honour the universal env var (git respects NO_COLOR since 2.21):
NO_COLOR=1 git diffcolor.diff / color.status / color.branch / color.grep / color.interactive —— 按命令覆盖
每个会发出着色输出的子命令都有自己的 color.<command> 键,对该命令覆盖 color.ui。可选值相同:auto、always / true、never / false。当你希望除某一条命令外都着色(例如把 git status 管道给脚本但仍希望 git diff 着色),或在企业 .gitconfig 禁用全局颜色后想为 diff 单独恢复时使用。
# Per-command keys, all default to value of color.ui:
git config --global color.diff auto
git config --global color.status auto
git config --global color.branch auto
git config --global color.grep auto
git config --global color.interactive auto
git config --global color.decorate auto # git log --decorate
git config --global color.pager true # respect color when paged
git config --global color.advice auto # hint messages
git config --global color.push auto # since git 2.41
git config --global color.remote auto # since git 2.21
# Example: force colour for diff specifically, leave everything else auto:
git config --global color.diff alwayscolor.<cmd>.<slot> —— 命名槽位调色板系统
每个子命令都有命名「槽位」—— 输出中可单独着色的元素。值的语法为 <前景> [<背景>] [<属性>...],颜色可为命名(red / green / yellow / blue / magenta / cyan / white)、256 调色板数字(231)或 24 位十六进制("#ff8000",git 2.26+)。属性:bold、dim、italic、underline、blink、reverse、strike。在 fg/bg/attr 前加 no- 可清除继承值。下方未列出的槽位回退到 git 内置默认。
# git diff slots — most commonly retuned for readability:
git config --global color.diff.meta "yellow bold"
git config --global color.diff.frag "magenta bold"
git config --global color.diff.func "cyan"
git config --global color.diff.context "white"
git config --global color.diff.old "red bold"
git config --global color.diff.new "green bold"
git config --global color.diff.whitespace "red reverse"
git config --global color.diff.commit "yellow"
# git status slots:
git config --global color.status.header "white"
git config --global color.status.added "green"
git config --global color.status.updated "green"
git config --global color.status.changed "yellow"
git config --global color.status.untracked "red"
git config --global color.status.branch "cyan bold"
git config --global color.status.nobranch "red reverse"
# git branch slots:
git config --global color.branch.current "green bold"
git config --global color.branch.local "white"
git config --global color.branch.remote "yellow"
git config --global color.branch.upstream "magenta"
git config --global color.branch.plain "white"
# git grep slots (git 2.0+):
git config --global color.grep.filename "magenta"
git config --global color.grep.linenumber "yellow"
git config --global color.grep.match "red bold"
git config --global color.grep.matchContext "white"
git config --global color.grep.separator "white"
# Truecolor (git 2.26+, 2020):
git config --global color.diff.new "#3fb950 bold"
git config --global color.diff.old "#f85149 bold"color.decorate.<slot> —— git log --decorate 引用着色
git log --decorate 为每个提交标注指向它的引用(分支、标签、HEAD、stash)。每种引用类型都有自己的槽位 —— 在浏览繁忙历史时若希望分支一色、标签一色、HEAD 突出显示,按下面调整即可。
# git log --decorate slots:
git config --global color.decorate.branch "green bold"
git config --global color.decorate.remoteBranch "red bold"
git config --global color.decorate.tag "yellow bold"
git config --global color.decorate.stash "magenta bold"
git config --global color.decorate.HEAD "cyan bold"
git config --global color.decorate.grafted "blue"
# Pair with a one-line graph to make refs even more legible:
git config --global alias.lg \
"log --graph --oneline --decorate --all"
# Then: git lg权威的全彩 shell 提示符配置 —— bash + zsh
git 附带 git-prompt.sh(在 contrib/completion/ 下),它为 bash / zsh 导出 __git_ps1。着色形式(GIT_PS1_SHOWCOLORHINTS=1)将分支 / 脏状态 / stash / 上游状态渲染为不同颜色。下面是权威接线 —— 把该块复制到 ~/.bashrc 或 ~/.zshrc。该块不使用 color.ui(它通过 \[\e[...m\] 括号自行构建 SGR,bash 将其视为零宽 —— 括号错了会破坏终端的行编辑)。
# ~/.bashrc — fully-coloured git prompt
# (Debian / Ubuntu / Fedora ship git-prompt.sh under
# /usr/share/git-core/contrib/completion/git-prompt.sh;
# Homebrew ships it under
# /opt/homebrew/etc/bash_completion.d/git-prompt.sh.)
source /usr/share/git/completion/git-prompt.sh
# Colour hints: branch (green) / dirty (yellow) / staged (red).
export GIT_PS1_SHOWCOLORHINTS=1
# Show + for staged changes, * for unstaged.
export GIT_PS1_SHOWDIRTYSTATE=1
# Show $ if anything is stashed.
export GIT_PS1_SHOWSTASHSTATE=1
# Show % if there are untracked files.
export GIT_PS1_SHOWUNTRACKEDFILES=1
# Show ↑/↓ counts vs upstream.
export GIT_PS1_SHOWUPSTREAM="auto verbose"
# \[ ... \] tells bash these bytes are zero-width — required
# for correct line-edit wrap math. PROMPT_COMMAND lets
# __git_ps1 splice the git status into PS1 each prompt.
PROMPT_COMMAND='__git_ps1 "\[\e[36m\]\u\[\e[0m\]@\[\e[35m\]\h\[\e[0m\]:\[\e[34m\]\w\[\e[0m\]" "\\\$ "'
# zsh equivalent (~/.zshrc) — drops \[ \] (zsh uses %{...%}):
# setopt PROMPT_SUBST
# source /usr/share/git/completion/git-prompt.sh
# PROMPT='%F{cyan}%n%f@%F{magenta}%m%f:%F{blue}%~%f$(__git_ps1 " (%s)") %# 'core.pager + LESS=FRX —— 为什么颜色有时到不了 pager
默认情况下 git 把 git log、git diff、git show、git branch -a 等输出通过 pager(多数系统上是 less)。管道不再是 TTY —— 但 git 知道它是把数据管到自己的 pager,于是仍像 TTY 一样注入颜色。坑在于:less 默认剥离控制字符,会把 SGR 转义渲染成 ^[[31m 字面噪音。修复是 LESS=FRX —— -R 保留 SGR、-F 在一屏内自动退出(短 diff 不会困在 less 里)、-X 跳过清屏(退出后 scrollback 仍保留 diff)。git 调用其默认 pager 时已自动设置 LESS=FRX —— 但若你用自定义命令覆盖 core.pager 或 GIT_PAGER,则需自行设置 LESS=FRX(或传 -R)。
# Inspect current pager (most systems: 'less').
git config --get core.pager
# Sane explicit form — leaves colour intact, quits on short output:
git config --global core.pager "less -FRX"
# Or set LESS globally and leave core.pager unset:
export LESS=FRX # add to ~/.bashrc
# Custom pager — REMEMBER to set the flags yourself:
git config --global core.pager "less -+F -+X -R" # don't auto-quit
# Disable the pager entirely (one-shot):
git --no-pager log
# Per-command pager override:
git config --global pager.diff "delta --side-by-side" # ships colour itself
git config --global pager.log "less -FRX +'/^commit'" # jump to first commit
git config --global pager.branch false # no pager for branch -a强制颜色通过管道 —— git log --color=always | less -R
每个 git 命令都接受单次调用的 --color={auto,always,never} 标志,会覆盖 color.ui 与按命令的键。规范用法是把数据管到非 git 自身 pager 的渲染器 —— less -R、bat、aha(HTML 转换),或 tee 时希望保留颜色。没有 --color=always,git 看到非 TTY 管道会自动剥离颜色。管道目标需能渲染 SGR 才有意义 —— less -R、bat、aha、delta、ansi2html。否则你看到的是 ^[[31m 字面噪音。
# Pipe coloured log into less manually (with -R to render SGR):
git log --color=always --graph --oneline | less -R
# Same idea with diff — useful with side-by-side viewers:
git diff --color=always | bat --paging=always
# Convert coloured diff to HTML for a code review email / blog post:
git log --color=always --graph -p HEAD~5..HEAD | aha > review.html
# Pipe coloured log into tee, keep on screen AND save to file:
git log --color=always --oneline | tee --output-error=warn /tmp/log.ansi
# Strip later when archiving (see /strip):
sed -E 's/\x1b\[[0-9;]*m//g' /tmp/log.ansi > /tmp/log.txt
# fzf with coloured input — needs --ansi flag:
git log --color=always --oneline | fzf --ansi配置键矩阵
git 所有与颜色相关的配置键、可接受的值、默认值、影响的子命令以及落地的 git 版本。未显式给出默认值的键回退到 color.ui。
| 键 | 值 | 默认 | 适用于 | 起始版本 |
|---|---|---|---|---|
| color.ui | auto · always · never · true · false | auto | all | 1.5.5 |
| color.diff | auto · always · never | color.ui | diff · show · log -p | 1.5.0 |
| color.status | auto · always · never | color.ui | status | 1.5.0 |
| color.branch | auto · always · never | color.ui | branch · branch -a | 1.5.0 |
| color.grep | auto · always · never | color.ui | grep | 1.5.6 |
| color.interactive | auto · always · never | color.ui | add -i · add -p · rebase -i | 1.5.0 |
| color.decorate | auto · always · never | color.ui | log --decorate | 1.5.6 |
| color.pager | true · false | true | any paged output | 1.5.6 |
| color.advice | auto · always · never | color.ui | advice hints | 2.18 |
| color.push | auto · always · never | color.ui | push | 2.41 |
| color.remote | auto · always · never | color.ui | fetch · remote | 2.21 |
相关参考
本站覆盖周边 ANSI / pager / CI 生态的相邻页面。
- 剔除 ANSI 转义码事后剔除已捕获 git 日志中 SGR 字节的正则 —— 把着色日志送往不渲染的聚合器时使用。
- ANSI 常见坑点相邻问题的「症状 → 成因 → 修复」—— pager 剥离颜色、less 字面渲染转义、
--color=always到了错误的下游。 - CI 日志中的 ANSI通过 FORCE_COLOR / --color=always / PTY 包装器,让 git 的着色输出穿过 GitHub Actions / GitLab / Jenkins 日志管道。
- ANSI 在野外ANSI 字节在真实系统中出现的位置 —— 容器日志、asciinema 录制、日志采集器、dotfile 框架 —— 以及各自的解码方法。