After building up a series of commits, one of the most valuable things you can do is look back at what happened — who changed what, when, and why. Git's history is a permanent, queryable record of every decision made on a project. The primary tool for reading that record is git log.
The Basic Log — git log
Running git log with no arguments lists all commits in the current branch in reverse chronological order — most recent first:
git log
commit ca82a6dff817ec66f44342007202690a93763949
Author: Wariz <wariz@example.com>
Date: Mon Mar 17 21:52:11 2024 -0700
Change version number
commit 085bb3bcb608e1e8451d4b2432f8ecbe6306e7e7
Author: Wariz <wariz@example.com>
Date: Sat Mar 15 16:40:33 2024 -0700
Remove unnecessary test
Each entry shows the full SHA-1 hash, the author name and email, the date, and the commit message. For a project with many commits, Git pipes the output through a pager — press q to exit.
Formatting the Output
git log has a rich set of options for controlling exactly what you see and how it is displayed.
--oneline — one commit per line
The most commonly used formatting flag. Each commit is condensed to a single line showing the abbreviated hash and the subject:
git log --oneline
ca82a6d Change version number
085bb3b Remove unnecessary test
a11bef0 Initial commit
This is invaluable for getting a quick overview of recent history without scrolling through walls of text.
-p or --patch — show the diff
Shows the full diff introduced by each commit — what lines were added and removed:
git log -p
git log -p -2 # Limit to the last 2 commits
Useful for code review or understanding exactly what a specific commit changed.
--stat — file-level statistics
Shows a summary of which files were modified in each commit and how many lines were added or removed:
git log --stat
commit ca82a6dff817ec66f44342007202690a93763949
Author: Wariz <wariz@example.com>
Date: Mon Mar 17 21:52:11 2024
Change version number
Rakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--pretty=format — custom output
For complete control over the output format:
git log --pretty=format:"%h - %an, %ar : %s"
ca82a6d - Wariz, 2 days ago : Change version number
085bb3b - Wariz, 4 days ago : Remove unnecessary test
Useful format specifiers:
| Specifier | Output |
|---|---|
%H | Full commit hash |
%h | Abbreviated commit hash |
%an | Author name |
%ae | Author email |
%ar | Author date, relative (e.g. "2 days ago") |
%ad | Author date, absolute |
%cn | Committer name |
%cr | Committer date, relative |
%s | Subject (commit message first line) |
--graph — branch visualisation
Adds an ASCII diagram of the branch and merge history alongside the log:
git log --oneline --graph
* 2d3acf9 Fix authentication bug
* 5e3ee11 Merge branch 'feature/login'
|\
| * 420eac9 Add login form component
* | 30e367c Update session timeout
|/
* d6016bc Initial project setup
This becomes particularly useful once you start working with branches — you can see at a glance where branches diverged and where they merged back.
Author vs. Committer
You may notice git log distinguishes between author and committer. The author is the person who originally wrote the change. The committer is the person who applied it to the repository. In a solo project they are always the same person. In collaborative projects — where patches are submitted and applied by a maintainer — they can differ.
Formatting Options Reference
| Option | Description |
|---|---|
--oneline | One line per commit (abbreviated hash + subject) |
-p / --patch | Show the diff introduced with each commit |
--stat | Show file change statistics per commit |
--shortstat | Show only the changed/insertions/deletions summary line |
--name-only | Show names of modified files |
--name-status | Show names and status (added/modified/deleted) |
--abbrev-commit | Show only the first few characters of the SHA-1 hash |
--relative-date | Show dates as relative ("2 weeks ago") |
--graph | ASCII graph of branch and merge history |
--pretty=format:"" | Custom format using specifiers |
Filtering the Output
git log is also a powerful search tool. You can narrow the output to exactly the commits you are looking for using filtering options.
By number of commits
Show only the most recent commits:
git log -3 # Last 3 commits
git log -10 # Last 10 commits
By date
git log --since=2.weeks # Last two weeks
git log --since="2024-01-01" # Since a specific date
git log --until="2024-06-01" # Before a specific date
git log --since="2 years 1 month ago" # Relative date formats
By author
git log --author="Wariz"
Shows only commits where the author name matches the string. Partial matches work.
By commit message
git log --grep="authentication"
Shows only commits whose message contains the search term. Case-sensitive by default.
By changed content — the pickaxe
git log -S "functionName"
The -S option (known as the "pickaxe") shows only commits that added or removed a specific string from the codebase. This is extremely useful for tracking when a specific function, variable, or piece of logic was introduced or removed.
By file or directory
git log -- src/app.js # Commits that touched this file
git log -- src/ # Commits that touched anything in this directory
The -- separator tells Git that what follows is a path, not a branch name. Always place path filters last in the command.
Excluding merge commits
git log --no-merges
In active repositories, merge commits can make up a large percentage of the history without adding meaningful information. --no-merges removes them from the output.
Combining Options
Options can be combined freely to build precise queries:
# All commits by Wariz in the last month, excluding merges, one line each
git log --author="Wariz" --since=1.month --no-merges --oneline
# All commits that touched the auth module with their diffs
git log -p -- src/auth/
# Visual branch history for the last 20 commits
git log --oneline --graph -20
Inspecting a Single Commit — git show
To examine a specific commit in detail — its metadata and the full diff it introduced:
git show ca82a6d # By abbreviated hash
git show HEAD # The most recent commit
git show HEAD~2 # Two commits before HEAD
Output includes the commit metadata (author, date, message) followed by the complete diff.
Comparing Commits — git diff
While git log navigates history, git diff compares specific points within it:
git diff HEAD~3 HEAD # Changes over the last 3 commits
git diff abc123 def456 # Changes between two specific commits
git diff main feature/login # Changes between two branches
git diff HEAD~1 HEAD -- src/app.js # Changes to a specific file between commits
Summary
| Command | What It Does |
|---|---|
git log | Full commit history, most recent first |
git log --oneline | Compact one-line view |
git log -p | History with diffs |
git log --stat | History with file statistics |
git log --graph --oneline | Visual branch history |
git log -<n> | Last n commits only |
git log --since=<date> | Commits after a date |
git log --author="<name>" | Commits by a specific author |
git log --grep="<term>" | Commits whose message matches a term |
git log -S "<string>" | Commits that added or removed a string |
git log -- <path> | Commits that touched a specific file or directory |
git log --no-merges | Exclude merge commits |
git show <hash> | Full details of a specific commit |
git diff <a> <b> | Differences between two commits or branches |