跳到主要内容
ansicode

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 等)会覆盖它。

.gitconfig / shell
# 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 diff

color.diff / color.status / color.branch / color.grep / color.interactive —— 按命令覆盖

每个会发出着色输出的子命令都有自己的 color.<command> 键,对该命令覆盖 color.ui。可选值相同:autoalways / truenever / false。当你希望除某一条命令外都着色(例如把 git status 管道给脚本但仍希望 git diff 着色),或在企业 .gitconfig 禁用全局颜色后想为 diff 单独恢复时使用。

.gitconfig / shell
# 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 always

color.<cmd>.<slot> —— 命名槽位调色板系统

每个子命令都有命名「槽位」—— 输出中可单独着色的元素。值的语法为 <前景> [<背景>] [<属性>...],颜色可为命名(red / green / yellow / blue / magenta / cyan / white)、256 调色板数字(231)或 24 位十六进制("#ff8000",git 2.26+)。属性:bolddimitalicunderlineblinkreversestrike。在 fg/bg/attr 前加 no- 可清除继承值。下方未列出的槽位回退到 git 内置默认。

.gitconfig / shell
# 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 突出显示,按下面调整即可。

.gitconfig / shell
# 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 将其视为零宽 —— 括号错了会破坏终端的行编辑)。

.gitconfig / shell
# ~/.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 loggit diffgit showgit 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.pagerGIT_PAGER,则需自行设置 LESS=FRX(或传 -R)。

.gitconfig / shell
# 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 -Rbataha(HTML 转换),或 tee 时希望保留颜色。没有 --color=always,git 看到非 TTY 管道会自动剥离颜色。管道目标需能渲染 SGR 才有意义 —— less -Rbatahadeltaansi2html。否则你看到的是 ^[[31m 字面噪音。

.gitconfig / shell
# 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.uiauto · always · never · true · falseautoall1.5.5
color.diffauto · always · nevercolor.uidiff · show · log -p1.5.0
color.statusauto · always · nevercolor.uistatus1.5.0
color.branchauto · always · nevercolor.uibranch · branch -a1.5.0
color.grepauto · always · nevercolor.uigrep1.5.6
color.interactiveauto · always · nevercolor.uiadd -i · add -p · rebase -i1.5.0
color.decorateauto · always · nevercolor.uilog --decorate1.5.6
color.pagertrue · falsetrueany paged output1.5.6
color.adviceauto · always · nevercolor.uiadvice hints2.18
color.pushauto · always · nevercolor.uipush2.41
color.remoteauto · always · nevercolor.uifetch · remote2.21

本站覆盖周边 ANSI / pager / CI 生态的相邻页面。