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 框架 —— 以及各自的解码方法。