跳到主要内容
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`。可选值相同:`auto`、`always` / `true`、`never` / `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+)。属性:`bold`、`dim`、`italic`、`underline`、`blink`、`reverse`、`strike`。在 `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 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`)。

.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 -R`、`bat`、`aha`(HTML 转换),或 `tee` 时希望保留颜色。没有 `--color=always`,git 看到非 TTY 管道会自动剥离颜色。管道目标需能渲染 SGR 才有意义 —— `less -R`、`bat`、`aha`、`delta`、`ansi2html`。否则你看到的是 `^[[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 生态的相邻页面。