👊

git-logのPRETTY FORMATの動くチートシートを作った

2024/03/02に公開

一言でいうと

PRETTY FORMAT作りバトルに終止符が打たれた

モチベーション

git-log--prettyオプションに引数を渡すと任意のフォーマットでコミットログ(以上のもろもろ)を出力できます。このフォーマットで使えるプレースホルダーがめっちゃ多い!覚えられない!つらい!

着想

単にプレースホルダーを一覧できるチートシートでも便利。それはそう。しかし、せっかくならプレースホルダーと実際の値を見比べながら使いたい。

これ、フォーマットで使えるプレースホルダーを実際の値と一緒に全部出力するフォーマットを作って、それをgit-logで使えばいいんじゃね?

実行例

できたので実行例を示します。https://github.com/ruby/ruby をチェックアウトして実行するとこう。便利すぎる…!PRETTY FORMATを指定することなんて正直一年に一度くらいしかないけど、便利すぎる…!

rei

実装

RubyのDATAはこんなときに便利ですね!

#! /usr/bin/env ruby

CLEAR   = "\e[0m"
BOLD    = "\e[1m"

COLORS = {
  black: "\e[30m",
  red: "\e[31m",
  green: "\e[32m",
  yellow: "\e[33m",
  blue: "\e[34m",
  magenta: "\e[35m",
  cyan: "\e[36m",
  white: "\e[37m",
}

COLORS.each do |color, value|
  define_method color do |s|
    "#{value}#{s}#{CLEAR}"
  end
end

pretty_format = "#{red '%h'} #{yellow '%aN'} %s\n"
pretty_format += DATA.each_line
  .each_slice(3)
  .map { _1.map &:strip }
  .reject { _1.first =~ /^%G./ } # Some may not configure GPG
  .map { "#{magenta "%" +_1}\t#{cyan _1}\t#{_2}\n" }
  .join

system('git', 'log', '--pretty=format:' + pretty_format)

# Taken from https://git-scm.com/docs/pretty-formats/2.44.0 

__END__
%H
commit hash

%h
abbreviated commit hash

%T
tree hash

%t
abbreviated tree hash

%P
parent hashes

%p
abbreviated parent hashes

%an
author name

%aN
author name (respecting .mailmap, see git-shortlog[1] or git-blame[1])

%ae
author email

%aE
author email (respecting .mailmap, see git-shortlog[1] or git-blame[1])

%al
author email local-part (the part before the @ sign)

%aL
author local-part (see %al) respecting .mailmap, see git-shortlog[1] or git-blame[1])

%ad
author date (format respects --date= option)

%aD
author date, RFC2822 style

%ar
author date, relative

%at
author date, UNIX timestamp

%ai
author date, ISO 8601-like format

%aI
author date, strict ISO 8601 format

%as
author date, short format (YYYY-MM-DD)

%ah
author date, human style (like the --date=human option of git-rev-list[1])

%cn
committer name

%cN
committer name (respecting .mailmap, see git-shortlog[1] or git-blame[1])

%ce
committer email

%cE
committer email (respecting .mailmap, see git-shortlog[1] or git-blame[1])

%cl
committer email local-part (the part before the @ sign)

%cL
committer local-part (see %cl) respecting .mailmap, see git-shortlog[1] or git-blame[1])

%cd
committer date (format respects --date= option)

%cD
committer date, RFC2822 style

%cr
committer date, relative

%ct
committer date, UNIX timestamp

%ci
committer date, ISO 8601-like format

%cI
committer date, strict ISO 8601 format

%cs
committer date, short format (YYYY-MM-DD)

%ch
committer date, human style (like the --date=human option of git-rev-list[1])

%d
ref names, like the --decorate option of git-log[1]

%D
ref names without the " (", ")" wrapping.

%S
ref name given on the command line by which the commit was reached (like git log --source), only works with git log

%e
encoding

%s
subject

%f
sanitized subject line, suitable for a filename

%b
body

%B
raw body (unwrapped subject and body)

%N
commit notes

%GG
raw verification message from GPG for a signed commit

%G?
show "G" for a good (valid) signature, "B" for a bad signature, "U" for a good signature with unknown validity, "X" for a good signature that has expired, "Y" for a good signature made by an expired key, "R" for a good signature made by a revoked key, "E" if the signature cannot be checked (e.g. missing key) and "N" for no signature

%GS
show the name of the signer for a signed commit

%GK
show the key used to sign a signed commit

%GF
show the fingerprint of the key used to sign a signed commit

%GP
show the fingerprint of the primary key whose subkey was used to sign a signed commit

%GT
show the trust level for the key used to sign a signed commit

%gD
reflog selector, e.g., refs/stash@{1} or refs/stash@{2 minutes ago}; the format follows the rules described for the -g option. The portion before the @ is the refname as given on the command line (so git log -g refs/heads/master would yield refs/heads/master@{0}).

%gd
shortened reflog selector; same as %gD, but the refname portion is shortened for human readability (so refs/heads/master becomes just master).

%gn
reflog identity name

%gN
reflog identity name (respecting .mailmap, see git-shortlog[1] or git-blame[1])

%ge
reflog identity email

%gE
reflog identity email (respecting .mailmap, see git-shortlog[1] or git-blame[1])

%gs
reflog subject

使い方

↑のRubyスクリプトを実行パスが通っているところに置いて、.gitconfigに下記のようなaliasを追加して使っています。本当はオプションとかを渡せたほうがいいですね。

[alias]
  log-pretty-cheatsheet = "!sh -c 'git-log-pretty-cheatsheet'"

感想

もっと早く作っておけばよかった

Discussion