32blogby Studio Mitsu

delta で git diff を見やすくする設定レシピ

delta は Rust 製の git diff ページャ。サイドバイサイド・行番号・navigate を .gitconfig に5行で設定する実戦レシピ。

by omitsu24 min read
目次

delta は Rust 製の git diff ページャ。シンタックスハイライト・サイドバイサイド表示・行番号・n/N キーでファイル間ジャンプができるようになる。インストールは apt install git-delta(パッケージ名は git-delta だがバイナリ名は delta)、~/.gitconfig に5行追加するだけで git diffgit showgit log -pgit blame がまとめて読みやすくなる。エイリアスもラッパーも不要で、Git 自身が delta にパイプしてくれる。

素の git diff は完全に1986年の遺物だ。追加行が緑、削除行が赤、それだけ。シンタックスハイライトもなければ行番号もないし、サイドバイサイドで比較する手段もない。40ファイルの PR を CLI で読もうとして、結局 VS Code を立ち上げた経験があるなら、その不便さの正体はもう知っているはずだ。エンジニアは1日のかなりの時間を diff を読むことに費やしているのに、デフォルトの Git 出力は当時の 16 色端末のままなのだ。

delta はそこを綺麗に埋めてくれるツールで、最近のドットファイルリポジトリでは半ば標準装備になっている。中身は Rust のシングルバイナリで、Git からはページャとして呼ばれる。シンタックスハイライトは bat と同じエンジン(syntect クレート)を使っているので、bat を入れている人なら見た目はほぼ地続きだ。この記事では ~/.gitconfig に最低限書く5行から、サイドバイサイド・navigate・カスタムデコレーションまで、実戦で使える設定レシピを順に解説する。

素の git diff が解決していない5つの問題

git diff は端末の表示色が16色しかなく、「diff ビューア = less に緑赤の ANSI を流すこと」だった時代に設計された。「変更を見せる」という1点では今でも仕事はしてくれるが、それ以上のことは何もしない。

delta はそこを5つ補ってくれる:

  1. シンタックスハイライトgit diff+/- の行を緑赤で塗るだけ。delta は syntect を使ってファイルの中身をパースし、追加・削除行の中でもキーワード・文字列リテラル・コメントが正しく色分けされる。200行のリファクタを「目を凝らして読む」から「眺めて把握する」に変わる
  2. サイドバイサイド表示 — GitHub や GitLab のレビュー UI が標準で side-by-side なのは、人間の脳が左右比較で差分を読むのに慣れているから。delta は1行の設定で同じレイアウトを端末に持ち込める。長い行は自動で折り返してくれる
  3. 行番号git diff@@ -42,7 +42,9 @@ というハンクヘッダしか出さず、そこから自分で数えろと言ってくる。delta は旧/新の行番号を2列のガッターで全行に表示する
  4. 大きな diff の中での移動n を押すと次のファイル、N で前のファイルに飛べる。git log -p ならコミット境界でも止まる。これがないと CLI で大きな PR を読むのは不可能に近い
  5. ワード単位の差分 — 1行のうち1文字だけ変わった場合、git diff は行ごと削除・追加する。delta は Levenshtein 距離で実際に変わった文字だけハイライトしてくれるので、本物の変更か空白いじりかが一目で分かる

delta のインストール(git-delta というパッケージ名の罠)

インストールは1コマンドで終わるが、初見で必ず引っかかる「パッケージ名」の罠がある。

powershell
# winget(Windows 11 標準)
winget install dandavison.delta

# Chocolatey
choco install delta

# Scoop
scoop install delta

Windows では PowerShell・Windows Terminal・WSL のどれでも動く。Windows 固有の注意点(端末の色深度や less.exe 周り)は Using Delta on Windows のページを参照。

インストール後にバージョン確認:

bash
delta --version
# delta 0.19.2 以降が出ればOK

公式インストールガイド には FreeBSD・Nix・conda までほぼ全てのパッケージマネージャがリストされている。

最低限の ~/.gitconfig は5行だけ

まずは何も考えず、この5行を ~/.gitconfig に貼ってほしい。delta の公式 Get Started ページに書いてあるそのままで、実際にユーザの 9 割はこの設定で使っている:

gitconfig
[core]
    pager = delta

[interactive]
    diffFilter = delta --color-only

[delta]
    navigate = true  # n と N でファイル間移動
    dark = true      # ライト端末なら light = true、自動判定なら省略

[merge]
    conflictStyle = zdiff3

これで終わり。~/.gitconfig を保存した瞬間から、Git の diff 系コマンドは全て delta 経由で表示されるようになる。公式マニュアルが対象と明記しているのは以下:

  • git diff
  • git show
  • git log -p
  • git stash show -p
  • git reflog -p
  • git add -p

5行それぞれの意味を補足しておく:

  • core.pager = delta — Git の diff 出力を delta に流す指定。これがないと何も始まらない
  • interactive.diffFilter = delta --color-onlygit add -p のハンクにも色を付ける指定。--color-only フラグは外せない。git add -p は diff のフォーマットをパースしてどこをステージするか決めているので、delta はフォーマットを書き換えず色だけ付ける必要がある
  • delta.navigate = trueless の中で n/N キーを有効化する。大きな diff を読むときに最も重要な機能で、わざわざ無効にする理由がない
  • delta.dark = true — ダーク端末用の色を選ばせる。ライト端末なら light = true。自動判定(両方とも省略)でも普通の端末なら動くが、lazygitzellijtmux の中で delta を呼ぶ場合は明示しておかないと検出に失敗することがある。これは Choosing colors マニュアル でも警告されている
  • merge.conflictStyle = zdiff3 — 厳密には delta の設定ではないが、delta は zdiff3 形式のコンフリクトを「マージベースから ours」「マージベースから theirs」の2つの diff として描画してくれる。<<<<<<< HEAD のブロックを睨んで自分の変更がどっちか思い出すあの作業から解放される

設定したらどこかの作業中リポジトリで git diff を叩いてみてほしい。シンタックスハイライト付きのファイルヘッダ・2列の行番号ガッター・n キーでファイル間移動が一気に体験できる。これがベースラインの見た目だ。

最低限の5行で 9 割は満たせるが、毎日 diff を読む人なら、ここからもう10分かけて設定を煮詰める価値はある。実戦で使っている全部入りの設定がこれだ:

gitconfig
[core]
    pager = delta

[interactive]
    diffFilter = delta --color-only

[delta]
    features = side-by-side line-numbers decorations
    navigate = true
    dark = true
    syntax-theme = OneHalfDark
    side-by-side = true
    line-numbers = true
    hyperlinks = true
    hyperlinks-file-link-format = "vscode://file/{path}:{line}"

[delta "decorations"]
    commit-decoration-style = bold yellow box ul
    file-style = bold yellow ul
    file-decoration-style = none
    hunk-header-decoration-style = yellow box

[delta "line-numbers"]
    line-numbers-left-format = "{nm:>4}┊"
    line-numbers-right-format = "{np:>4}│"
    line-numbers-left-style = blue
    line-numbers-right-style = blue

[merge]
    conflictStyle = zdiff3

ポイントを順番に:

  • features = ... は名前付きグループのリスト。各グループは [delta "name"] セクションになる。delta の設定が長くなりがちな問題を解消するための仕組みで、関連オプションをひとまとまりにして名前を付けて、features 行で有効化する。継承ルールは features-named-groups-of-settings マニュアル を参照
  • syntax-theme = OneHalfDark で bat 互換のテーマを指定する。delta は内部で bat を Rust クレートとして取り込んでいるので、bat と同じテーマがそのまま使える。delta --show-syntax-themes を叩くと、自分の端末で全テーマがコードサンプル付きで描画されるので、目で見て選べる
  • side-by-side = true で 2 ペイン表示を有効化。長い行は自動で折り返され、矢印マーカで折り返し位置を示してくれる。挙動を細かく制御したい場合は side-by-side マニュアル--wrap-max-lines などを参照
  • hyperlinks = true はコミットハッシュやファイルパスを端末ハイパーリンクに変える。上の設定だとファイルパスをクリックすると VS Code が開く。Cursor なら cursor://...、JetBrains なら idea://... などに差し替え可能。詳細は hyperlinks マニュアル
  • line-numbers-left/right-format は行番号ガッターの見た目。{nm} が旧(minus)行番号、{np} が新(plus)行番号。Unicode 罫線文字( )は完全に趣味だが、レビューツールっぽい見た目になる

サイドバイサイドをコマンドラインで一時的にON/OFF

サイドバイサイドはコードレビューには最高だが、1行のタイポ修正には大袈裟だ。delta には DELTA_FEATURES 環境変数があって、設定ファイルを書き換えずに features を切り替えられる:

bash
# gitconfig の設定に side-by-side を一時的に追加
export DELTA_FEATURES=+side-by-side

# gitconfig の設定に戻す
export DELTA_FEATURES=+

+ プレフィックスは「既存の features に追加する」という意味で、置き換えではない。git log -p 1回だけサイドバイサイドで読みたいとき用のパターンとして覚えておくと便利。これは features-named-groups-of-settings ページ で紹介されている使い方だ。

テーマと色のカスタマイズ

delta はテーマを自動で選んでくれるが、入れた次に必ずやりたくなるのがテーマ変更だろう。delta の色には大きく2層あって、それを意識すると設定がスムーズになる:

  1. シンタックステーマ — ハンク内のコードの色(OneHalfDark などの bat 互換テーマ)
  2. delta スタイル+/-/ガッター/装飾の色(--minus-style--plus-style などで個別指定)

シンタックステーマ(コードの色)

bash
# 全テーマをコードサンプル付きで表示
delta --show-syntax-themes

# パイプしてスクロールしながら見たい場合
delta --show-syntax-themes | less -R

delta のシンタックステーマは bat と全く同じ .tmTheme ファイル群だ。ダーク端末で人気なのは OneHalfDarkMonokai ExtendedDraculagruvbox-dark あたり。ライト端末なら GitHubOneHalfLightSolarized (light)。自前の Sublime Text テーマを持ち込みたい場合は $(bat --config-dir)/themes/.tmTheme を置いて bat cache --build を実行する。

delta スタイル(delta が自分で描く部分)

+/-/ガッターの色は --minus-style--plus-style--zero-style などで制御する。スタイル文字列の文法は Git の color 設定と同じ:

gitconfig
[delta]
    minus-style = syntax "#3f1f1f"
    plus-style = syntax "#1f3f1f"
    minus-emph-style = syntax bold "#7f1f1f"
    plus-emph-style = syntax bold "#1f7f1f"

syntax というキーワードは「前景色はシンタックスハイライタが選んだ色を使う」という指定。これが delta の地味に賢いところで、背景に色を付けても前景は元の構文色のまま残るので、追加・削除の塗りつぶしが入っていてもコード自体は普通に読める。

スタイル指定可能な要素は delta --helpSTYLES セクションに全部載っている。同じリファレンスは Choosing colors マニュアル でも参照できる。

git diff だけじゃない:blame・grep・merge・stash

delta は Git のページャとして登録されているので、diff か blame を出すコマンドは全部自動で恩恵を受ける。「あって良かった」レベルから「これがないと無理」レベルに上がるユースケースが4つある。

git blame をハイパーリンク付きで

bash
git blame src/handlers.rs

上の設定(hyperlinks = true)が入っていれば、blame 出力のコミットハッシュが GitHub・GitLab・SourceHut・Codeberg のコミットページへのクリック可能なリンクになる。ハッシュをクリックするとブラウザで PR が開く。リモート URL の検出方法は git-blame マニュアル を参照。

blame に明示的に delta を指定したい場合(デフォルトでない環境もある):

gitconfig
[pager]
    blame = delta

マージコンフリクト(zdiff3 + delta)

長期ブランチでひどいマージコンフリクトを踏んだことがある人にとってのキラー機能はこれだ。merge.conflictStyle = zdiff3 を設定しておくと、delta はコンフリクトを「マージベース → ours」と「マージベース → theirs」の2つの diff として描画する:

bash
git merge feature-branch
# コンフリクト発生
git diff

<<<<<<< ======= >>>>>>> の3ブロックではなく、両側が実際に何を変えたのかが diff として見える。1度見ると素のコンフリクトマーカは16進ダンプを読んでいるような気分になる。詳しい見た目は merge-conflicts マニュアル で。

rg や git grep の出力を色付きで

delta は grep 出力も整形してくれる。ripgrep をパイプすると、各マッチのファイルガッター込みでシンタックスハイライトされる:

bash
# rg --json が推奨フォーマット
rg --json -C 2 'fn handle_' src/ | delta

--json は重要。普通の rggrep の出力は delta が解釈に迷うパターンがあるが、JSON にすると曖昧さがなくなる。これは grep マニュアル に推奨パターンとして書かれている。ripgrep 自体の使い方は ripgrep 完全ガイド を参照。

git stash show -p と git reflog -p

これは小さい勝ちだが地味に効く。diff を出すコマンドは全部自動で delta が掛かるので、git stash show -p がちゃんとレビューできる見た目になるし、git reflog -p を遡って自分の変更を読むのが苦じゃなくなる。設定は何もいらない。core.pager = delta だけで全部カバーされる。

FAQ

delta は git diff を置き換えるツールなの?

正確にはどちらでもない。delta は ページャ だ。Git は今まで通り git diff を実行して同じ diff テキストを出力し、その出力を表示する段階で delta にパイプしている。Git の diff の計算ロジックは何も変わらない。git diff > file.diff のようにファイルにリダイレクトしているスクリプトはそのまま動く。Git は stdout が TTY のときだけページャを起動するからだ。これは git log と同じ規約。

delta をパイプしたら色が消えるんだけど?

batlsgrep と同じ規約で、delta は stdout が TTY かどうかを自動判定する。tee にパイプしたりファイルにリダイレクトすると delta はプレーン出力に切り替わる。強制的に色を出したい場合は --color-only を指定するか、Git 側の pager フラグを調整する。スクリーンショットや PDF 用に色付きで保存したい場合は export to HTML/PDF tipahaansifilter を使う方法が紹介されている。

サイドバイサイドを一時的に切るには?

bash
git -c delta.side-by-side=false log -p

-c フラグは1コマンドだけ任意の Git config を上書きできる。設定ファイルを触らずに一時的に切り替える一番きれいな方法だ。同じパターンが Configuration マニュアルdelta.line-numbers=false の例として紹介されている。

delta と diff-so-fancy と diff-highlight、どれを使うべき?

delta が今のところモダン勢の本命だ。diff-highlight は Git 同梱の Perl スクリプトで、ワード単位ハイライトしかしない。diff-so-fancy は 2016 年頃に出た diff-highlight の bash ラッパー。delta はこの2つよりも新しく(Rust、2018+)、速く、両者の機能に加えて side-by-side・navigate・シンタックスハイライト・マージコンフリクト整形までやってくれる。さらに delta には --diff-highlight--diff-so-fancy のエミュレーションモードもあるので、見た目だけ昔ながらにしたい場合も対応できる。

Git 以外、Mercurial や Jujutsu でも使える?

使える。delta は標準の unified diff 形式を入力として受け付けるので、unified diff を出すツールなら何でも繋げられる。Jujutsu なら ~/.config/jj/config.toml に以下を追加:

toml
[ui]
pager = "delta"
diff-formatter = ":git"

これは delta Configuration マニュアル の Jujutsu セクションに書かれている。Mercurial なら hgrcpager = delta で OK。

巨大リポジトリで git log -p が遅くならない?

実用上は気にならない。delta は diff 出力を行ごとに処理して less にストリームしているので、体感の遅延は素の git log -p と同じ(遅いのは Git 側)。1万コミットの履歴に -p を付けても delta が追加するオーバーヘッドは数百ミリ秒程度で、しかもシンタックスハイライトのコストは less でスクロールして見えた範囲にしか掛からない。本当に最速にしたい場合は syntax-theme = none でハイライトを切れば、一番高いコストが消える。

bat を更新したら delta がクラッシュするんだけど?

一番よくある原因は、delta がリンクしている bat と違うバージョンで bat cache --build を実行したケース。delta は bat を Rust クレートとして取り込んでいるので、ローカルの bat キャッシュのフォーマットが違うとメモリエラーで落ちる。修正は delta の Cargo.toml に書かれているのと同じバージョンの bat を入れてキャッシュを作り直すこと。delta 0.19+ は bat 0.26 以降が必要。

まとめ

~/.gitconfig に5行貼るだけで delta は仕事を始めてくれる。新しい開発環境を作ったらまずこれを入れて git diff を1回叩いてみてほしい。なぜこのツールが今のドットファイルリポジトリに必ず入っているかが瞬時に分かる。フル装備の設定(サイドバイサイド・navigate・hyperlinks・カスタム装飾)も追加で10分の作業で、PR を端末で読むたびに元が取れる。

delta が属しているのはモダンなシェル一式の文脈だ。ファイルは bat、検索は ripgrep、diff は delta、全部がテーマと規約を共有している。1度設定してドットファイルリポジトリに入れておけば、新しいマシンに移っても同じ体験が付いてくる。Rust 製ツールがなぜ GNU 純正よりも速いのかは Rust 製 CLI が爆速な理由 に、どの古典ツールがどのモダン置き換えに対応するかは CLI ツールマップ にまとめてある。