Custom Log Formatting
Default git log output is verbose and noisy. The formatting flags let you turn it into anything from a one-line summary to a machine-parseable feed. Once you learn the placeholder vocabulary, you can build a log alias tailored to exactly the way you read history.
Built-in pretty formats
git log --oneline # <short-sha> <subject> git log --short # author + subject git log --medium # default — author, date, subject, body git log --full # adds committer git log --fuller # adds author date AND commit date separately git log --reference # GitHub-style "1f9ab2c (Add login form, 2026-05-15)" git log --email # mbox-style headers — handy for patches git log --raw # mode + sha pairs for each file change
--fuller
commit 1f9ab2c0e8b4a7d2f0c...
Author: Alice <alice@example.com>
AuthorDate: Mon May 13 10:00:00 2026 +0000
Commit: release-bot <bot@example.com>
CommitDate: Mon May 13 11:00:00 2026 +0000
Add login form validation--pretty=format: and placeholders
--pretty=format:"..." is the workhorse. You write a template string with % placeholders and Git fills it in for every commit.
Placeholder | Meaning |
|---|---|
| Full commit hash |
| Abbreviated commit hash (7 chars by default) |
| Full / short tree hash |
| Full / short parent hashes (space-separated) |
| Author name / email |
| Committer name / email |
| Author date (respects |
| Author date, relative ("3 hours ago") |
| Author date, strict ISO 8601 |
| Committer date variants |
| Committer date as Unix timestamp |
| Subject (first line of commit message) |
| Body (everything after the subject) |
| Full raw message (subject + body) |
| Ref names like " (HEAD -> main, origin/main)" |
| Ref names without parentheses |
| Signature verification status (G/B/U/N) |
| Newline |
Adding colour
Colour codes inside the format string
git log --pretty=format:"%C(yellow)%h%Creset %C(green)%an%Creset %s" # Available colours: # %C(red) %C(green) %C(yellow) %C(blue) %C(magenta) %C(cyan) %C(white) # %C(bold) %C(dim) # %C(auto) — colour only when output is a terminal # %Creset — back to default
Rendered output
1f9ab2c Alice Add login form validation d4b1e0c Bob Merge branch 'feature-x' 5a2c7e3 Alice Add validation helper
Controlling date format
git log --date=short # 2026-05-13 git log --date=iso # 2026-05-13 10:00:00 +0000 git log --date=iso-strict git log --date=relative # "3 hours ago" git log --date=human # "Mon May 13 10:00" git log --date=raw # 1747130400 +0000 git log --date=unix # 1747130400 # Custom strftime-style format git log --date=format:"%Y-%m-%d %H:%M"
Building the perfect log alias step by step
Let's build a log alias that shows hash, refs, subject, relative date, and author, with colours and a graph. Start minimal and add a piece at a time:
Step 1 — bare bones
git log --pretty=format:"%h %s"
Step 2 — add author and relative date
git log --pretty=format:"%h %s (%cr) <%an>"
Step 3 — add colour
git log --pretty=format:"%C(yellow)%h%Creset %s %C(green)(%cr)%Creset %C(blue)<%an>%Creset"
Step 4 — add ref names and a graph
git log --graph --abbrev-commit \ --pretty=format:"%C(yellow)%h%Creset%C(red)%d%Creset %s %C(green)(%cr)%Creset %C(blue)<%an>%Creset"
Step 5 — save as an alias
git config --global alias.lg "log --graph --abbrev-commit --pretty=format:'%C(yellow)%h%Creset%C(red)%d%Creset %s %C(green)(%cr)%Creset %C(blue)<%an>%Creset'" # Now just: git lg git lg --all git lg -20
Machine-readable output (JSON-ish)
For scripts you usually want a delimiter that won't appear in commit messages. Use a unit-separator (\\x1f) or a tab.
Tab-separated for easy cut/awk
git log --pretty=format:"%H%x09%an%x09%ae%x09%ct%x09%s"
# %x09 = tab character
# Then in shell:
git log --pretty=format:"%H%x09%an%x09%ct%x09%s" \
| awk -F'\t' '{print $2, "->", $4}'JSON-shaped output
git log --pretty=format:'{"sha":"%H","author":"%an","date":"%cI","subject":"%s"},'
# Wrap in [ ... ] and trim the trailing comma in post-processing.
# For bullet-proof JSON, use a real script that escapes %s — commit
# messages can contain quotes and backslashes.A starter kit of aliases
Five aliases you'll actually use
# lg — pretty graph log git config --global alias.lg "log --graph --abbrev-commit --pretty=format:'%C(yellow)%h%Creset%C(red)%d%Creset %s %C(green)(%cr)%Creset %C(blue)<%an>%Creset'" # last — the last commit, full detail git config --global alias.last "log -1 --stat" # today — what landed today git config --global alias.today "log --since=midnight --oneline" # mine — your own commits this week git config --global alias.mine "!git log --author=\"$(git config user.email)\" --since='1 week ago' --no-merges --pretty=format:'%h %ad %s' --date=short" # changelog — release notes between two refs (use: git changelog v1.0..v2.0) git config --global alias.changelog "log --pretty=format:'* %s (%h, %an)' --no-merges"
git changelog v1.0..v2.0
* Add login form validation (1f9ab2c, Alice) * Tighten password rules (b3a9f00, Alice) * Add validation helper (5a2c7e3, Alice) * Fix README typos (c204c1d, Bob)
git config --global log.date short. You can still override per-command with `--date=`.