Difficulty: Beginner
How do you explore Git history? Explain git log, git show, git blame, and git reflog.
Git provides several powerful tools for exploring project history:
git log: Shows commit history. Has many formatting options like --oneline, --graph, --author, --since, and --grep to filter and display commits in useful ways.
git show: Displays detailed information about a specific commit including the diff, author, date, and message.
git blame: Shows who last modified each line of a file and in which commit. Essential for understanding why a line was changed.
git reflog: Records every movement of HEAD, even operations that rewrite history. It is your safety net - you can recover from almost any mistake using reflog because it tracks commits even after they are unreachable from any branch.
# Basic log
git log
# Compact one-line format
git log --oneline
# a1b2c3d feat: add auth module
# e4f5g6h fix: resolve CORS issue
# Visual branch graph
git log --oneline --graph --all
# * a1b2c3d (HEAD -> main) Merge feature/auth
# |\
# | * e4f5g6h feat: add login endpoint
# | * i7j8k9l feat: add register endpoint
# |/
# * m0n1o2p chore: initial setup
# Filter by author
git log --author="John" --oneline
# Filter by date range
git log --since="2024-01-01" --until="2024-06-30" --oneline
# Filter by commit message
git log --grep="fix" --oneline
# Show files changed in each commit
git log --stat --oneline
# a1b2c3d feat: add auth module
# src/auth/login.ts | 45 +++++++++++++
# src/auth/routes.ts | 12 ++++
# 2 files changed, 57 insertions(+)
# Custom pretty format
git log --pretty=format:"%h %an %ar - %s" -10
git log --oneline --graph --all is the most useful form - it shows all branches visually. Add --stat to see which files changed.
# Show details of a specific commit
git show a1b2c3d
# commit a1b2c3d...
# Author: John <john@example.com>
# Date: Mon Jan 15 10:30:00 2024
#
# feat: add auth module
#
# diff --git a/src/auth/login.ts b/src/auth/login.ts
# +export async function login(email, password) {...}
# Show a file at a specific commit
git show a1b2c3d:src/auth/login.ts
# Blame: who changed each line
git blame src/auth/login.ts
# a1b2c3d (John 2024-01-15) export async function login(...) {
# e4f5g6h (Jane 2024-02-01) const user = await findUser(email);
# e4f5g6h (Jane 2024-02-01) if (!user) throw new Error('Not found');
# Blame a specific line range
git blame -L 10,20 src/auth/login.ts
# Show what changed between two commits
git diff a1b2c3d..e4f5g6h
# Show what changed between branches
git diff main..feature/auth
git blame is invaluable for understanding why code was written. Use it with git show to see the full context of a change.
# Reflog records every HEAD movement
git reflog
# a1b2c3d HEAD@{0}: commit: feat: add auth
# e4f5g6h HEAD@{1}: checkout: moving from feature to main
# i7j8k9l HEAD@{2}: commit: wip: broken code
# m0n1o2p HEAD@{3}: reset: moving to HEAD~1
# SCENARIO: You accidentally ran git reset --hard
# and lost commits. Reflog saves the day:
git reflog
# Find the commit hash BEFORE the reset
git reset --hard a1b2c3d # restore to that point
# SCENARIO: You deleted a branch by mistake
git branch -D feature/important
# Oh no! But reflog has it:
git reflog
# Find the last commit on that branch
git checkout -b feature/important a1b2c3d
# Reflog entries expire after 90 days (default)
# For unreachable commits, 30 days
# Search reflog
git reflog --grep-reflog="checkout"
Reflog is Git's undo history. Even after reset --hard or branch deletion, reflog keeps references for 30-90 days. Always check reflog before panicking.
git log, git show, git blame, History Navigation, Reflog