Git Log
Navigate history with log formats, follow a single file, and inspect one commit until the snapshot and message are both clear.
History is an evidence system
What git log actually reads
Commits form a directed graph. Each ordinary commit names one parent, a merge commit names two or more parents, and the first commit has none. A branch such as main points to one commit; HEAD normally points to the current branch. git log starts from a revision—HEAD by default—and walks reachable parents.
HEAD → main8f42d91Document journal evidence
PARENT39c0ae6Add reusable entry template
ROOT2a71b4cInitialize learning journal
Default log output is newest first, but presentation order is not a new relationship stored inside a commit. Parent IDs define ancestry. Dates help humans navigate; they do not replace the graph.
Read a commit record
Object ID
- The full hexadecimal name identifies the commit object.
- A short prefix is convenient only while it remains unique.
- Copy enough characters for the repository and context.
Snapshot + parent + message
- The tree identifies the project snapshot.
- Parent links place it in history.
- Author and committer metadata record roles and times.
- The message explains the intended change.
git log -1 --format=fuller makes the author/committer distinction visible. The author represents who originally wrote the change; the committer records who created this commit object. Rebases, patches, and integrations can make those people or timestamps differ.
Build a compact history map
git log --oneline --decorate --graph --all
# Example shape:
* 8f42d91 (HEAD -> main) Document journal evidence
* 39c0ae6 Add reusable entry template
* 2a71b4c Initialize learning journal--oneline
Shows one abbreviated ID and subject per commit. Use it to orient yourself, not as the final review.
--decorate
Shows branch, tag, HEAD, and remote-tracking ref names that currently point at displayed commits.
--graph
Adds text lanes for parent relationships. The drawing is structure, not a timeline measured to scale.
--all
Uses all refs as starting points so another local branch does not disappear from the map.
Test what you learned
Type the option that adds branch and tag names beside commits in git log.
Format output for the question
Readable history is contextual. A terminal investigation, release note, script, and code review need different fields. Git’s pretty formats let you choose them instead of parsing the default prose.
git log -5 --pretty=format:'%h %ad %an %s' --date=short
git log -5 --pretty=format:'%C(auto)%h%d %s %C(dim)(%cr)%C(reset)'
# Stable separators are safer for machine processing:
git log -5 --pretty=format:'%H%x09%aI%x09%an%x09%s'%H and %h
Full and abbreviated commit object IDs.
%an and %ae
Author name and email stored in the commit.
%aI and %cr
Strict author ISO date and relative committer date.
%s and %b
Message subject and body.
Inspect one commit with git show
git show defaults to HEAD. Given a commit, it prints metadata and normally the patch from its first parent to that commit. Start with scope, then open the detail you need.
git show --stat 8f42d91
git show --name-status 8f42d91
git show --format=fuller 8f42d91
git show 8f42d91 -- entries/2026-09-19-git-history.mdIDENTIFYName the exact commitResolve the ID from a trusted log result, branch, tag, or reviewed link.
ORIENTRead metadata and statConfirm subject, author, date, parent, affected paths, and approximate size.
INSPECTRead the patchLook for behavior changes, accidental files, generated output, and whether the message matches the diff.
VERIFYOpen the snapshot when neededgit show COMMIT:path/to/fileprints that path exactly as stored in the named snapshot.
A merge commit is more complicated because it has multiple parents. Default output may not tell the whole integration story. Use git show --diff-merges=first-parent, git show -m, or git show --cc only after deciding which parent comparison answers your question.
Test what you learned
Type the command that prints README.md exactly as stored in commit 8f42d91.
Follow one path through history
# Commits touching one path
git log --oneline -- README.md
# Follow one file across a simple rename
git log --follow --oneline -- docs/guide.md
# Find commits that changed the count of this exact string
git log -S"PAYMENT_API_KEY" --oneline --all
# Find patches whose changed lines match a regular expression
git log -G"fetch\(|axios\." --oneline -- src/The -- separator tells Git that what follows is a path, not another revision. Use it whenever names could be ambiguous. Path-limited history answers “which displayed commits touched this path?” It does not prove that unrelated commits had no effect on the behavior you are investigating.
-SString count changed
Find commits where the number of occurrences of an exact string changed. This is useful for discovering when a constant, field, or call entered or left a patch.
-GChanged line matched
Find patches with added or removed lines matching a regular expression. This is useful when syntax varied but a pattern still identifies the change.
Filter by evidence, not convenience
git log --author='Ada' --oneline
git log --since='2026-09-01' --until='2026-09-30' --oneline
git log --grep='authentication' --regexp-ignore-case --oneline
git log --no-merges --oneline
git log --merges --oneline
git log main..feature/search --oneline
git log feature/search..main --onelineFilters narrow the result set; they do not certify intent. Author text can vary, commit subjects can omit a keyword, and dates depend on metadata and timezone. Treat an empty result as “nothing matched this query,” not “the event never happened.”
A..B
Commits reachable from B that are not reachable from A. Direction matters.
A...B
The symmetric difference: commits unique to either side, excluding their shared history.
--first-parent
Follow the mainline parent through merges, useful for reading integration history.
--ancestry-path A..B
Restrict the range to commits on an ancestry path between the endpoints.
Guided practice: audit a small history
Use the learning-journal repository from Unit 1 or create a disposable repository with at least three commits. Never paste output containing private paths, emails, or secret values into public evidence without reviewing it.
- 01Draw the graph
Run
git log --oneline --decorate --graph --all. Name HEAD, the current branch tip, the root commit, and each parent relationship. - 02Choose one commit
Copy a unique ID and inspect it with
--stat,--name-status, and the full patch. - 03Verify one snapshot
Print a known file with
git show COMMIT:pathand explain why it may differ from the working copy. - 04Trace one path
Use
git log --oneline -- path, then inspect the relevant commit with a path-limited show. - 05Write an evidence note
Record the command, commit ID, observation, and conclusion. Separate what the output proves from what you infer.
Independent lab: answer a history question
Create a disposable repository with a README and a source file. Make four coherent commits: initialize the project, add a configuration value, rename the source file with git mv, and update the configuration value. Then produce an audit that:
- Shows the complete decorated graph.
- Identifies the commit introducing the original configuration string with
-S. - Uses
--followto show the source file before and after its rename. - Uses
git show --statand a path-limited patch for one commit. - Prints the README from the second commit without checking it out.
- Explains the difference between the author, committer, parent, and tree fields.
- States one limitation of the query evidence.
Common history-reading mistakes
Treating the latest date as ancestry
Parent links define the graph. Author and committer dates can differ or be rewritten.
Reading only subjects
A subject is a claim. Inspect the affected files and patch before relying on it.
Assuming short IDs never change
A prefix can become ambiguous as the repository grows. Lengthen it when Git asks.
Forgetting hidden branches
Plain log starts from the current revision. Add explicit revisions or --all when the question spans refs.
Confusing snapshot with patch
A commit stores a snapshot; show usually derives a patch by comparing it with a parent.
Overclaiming from no results
A filter proves only that no reachable displayed commit matched the supplied conditions.
Lesson review
You can now use git log as a query over reachable commit history and git show as a focused inspection tool. You can move from graph orientation to exact evidence, follow one path, search changed content, and explain the limits of every result.
- I can distinguish refs, commit IDs, parent links, snapshots, and derived patches.
- I use compact formats to orient myself and full metadata or patches to verify claims.
- I separate revisions from paths with
--when ambiguity is possible. - I know when to use path history,
-S,-G, author, message, and date filters. - I describe what a history query proves without treating missing results as universal proof.