| Tested on | Ubuntu 26.04 LTS (Resolute Raccoon) |
|---|---|
| Package | git 2.53.0 |
| Applies to | Any host with Git installed |
| Privilege | Normal user |
| Scope | Inspecting commits (metadata and patch), reading files at a revision, viewing annotated tags and blob objects, and comparing a file across commits with git diff. Does not cover interactive history browsers or GUI clients. |
| Related guides | Git diff examples Git reflog tutorial Git tag tutorial Git commit message Git restore examples |
git show answers a question you ask dozens of times in a week: what exactly did that commit change? It prints the commit message, author, date, and the patch in one shot. You can also point it at a tag, a blob id, or a commit:path pair to read old file contents without checking out the revision.
The examples below use a small repo under ~/git-show-lab/. Every command was run on the lab host; output is trimmed where noted. Commit hashes and timestamps in the samples depend on when you run the lab — the relative refs (HEAD, HEAD~1, HEAD~2) stay the same.
What git show does
With no arguments, git show displays HEAD — the commit your branch currently points to:
git showcommit <hash>
Author: Lab User <lab@golinuxcloud.test>
Date: ...
Add app.py
diff --git a/app.py b/app.py
new file mode 100644
index 0000000..626799f
--- /dev/null
+++ b/app.py
@@ -0,0 +1 @@
+v1The header block is commit metadata; everything after the blank line is the unified diff Git recorded for that commit. That is the same information you would get from git log -1 plus git diff for the commit's parent, but in one command.
git show vs git log vs git diff
These three commands overlap in daily use but serve different jobs:
| Command | Primary job | Typical output |
|---|---|---|
git show |
Inspect one or more Git objects, typically a specific commit | Commit header + patch for that revision |
git log |
Walk history | One line or full header per commit; no patch unless you add -p |
git diff |
Compare two states | Patch only — no commit message block |
Use git show when you want to inspect a specific commit or other Git object; it can also accept multiple objects. Use git diff examples when you are comparing branches, the index, or two arbitrary commits. Use git log (or git reflog) to find a hash first.
Lab setup
Create a repo with three commits and an annotated tag. The later examples use relative refs, not fixed hashes:
mkdir -p ~/git-show-lab && cd ~/git-show-labInitialize Git and set the lab identity (matches the sample output below):
git init && git config user.email "lab@golinuxcloud.test" && git config user.name "Lab User"Add the first file and commit:
printf 'line one\n' > README.md && git add README.md && git commit -m "Initial README"Extend README and add a second commit:
printf '\nline two\n' >> README.md && git add README.md && git commit -m "Add second line to README"Add app.py and tag the result:
printf 'v1\n' > app.py && git add app.py && git commit -m "Add app.py" && git tag -a v1.0 -m "Release 1.0"Confirm the history and note how each ref maps to a subject line:
git log --oneline<hash> Add app.py
<hash> Add second line to README
<hash> Initial READMEYour hashes will differ from the sample; the relative positions do not:
| Ref | Commit subject |
|---|---|
HEAD |
Add app.py |
HEAD~1 |
Add second line to README |
HEAD~2 |
Initial README |
View commit details
Latest commit with HEAD
git show HEAD is equivalent to bare git show, because HEAD is the default object when no argument is supplied:
git show HEADThe output matches the default git show block above: metadata plus the app.py patch.
A specific commit by hash
Relative refs cover most cases. When you need an explicit hash — for a script, a code review link, or a commit outside your current branch — list history and copy the id:
git log --onelineCopy the hash for Add second line to README; your hash will differ from any sample here. Then pass it to git show:
git show HEAD~1commit <hash>
Author: Lab User <lab@golinuxcloud.test>
Date: ...
Add second line to README
diff --git a/README.md b/README.md
index 2d00bd5..b6e4dcf 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
line one
+
+line twoHEAD~1 and an explicit hash for the same commit produce the same output. Here HEAD~1 is the Add second line to README commit because HEAD is Add app.py — the same revision suffix works with git checkout and git diff.
Control how much output you see
Metadata only (--no-patch or -s)
When you only need the commit header and not the diff, suppress the patch:
git show -s HEADcommit <hash>
Author: Lab User <lab@golinuxcloud.test>
Date: ...
Add app.py-s is shorthand for --no-patch. You still get author and date — not just the subject line.
Subject line only
To print only the one-line subject (for scripts or quick checks), set --format:
git show -s --format=%s HEADAdd app.pyPair --format with -s whenever you want machine-friendly fields without the diff.
Diff summary with --stat
--stat keeps the commit header and replaces the full patch with a per-file line count:
git show --stat HEADcommit <hash>
Author: Lab User <lab@golinuxcloud.test>
Date: ...
Add app.py
app.py | 1 +
1 file changed, 1 insertion(+)Useful before a code review when you only need file names and change size.
File names with --name-only and --name-status
--name-only lists changed paths after the commit header:
git show --name-only HEADcommit <hash>
...
app.py--name-status adds a single-letter status before each path (A added, M modified, D deleted):
git show --name-status HEAD...
A app.pyRead a file at a past revision
Git accepts revision:path to dump blob contents without checking out the commit. To read README.md as it existed one commit before HEAD:
git show HEAD~1:README.mdline one
line twoTo read the initial version from two commits back:
git show HEAD~2:README.mdline oneThis is handy when you want to copy old content into your working tree with git restore or compare mentally against the current file.
Compare a file across two commits
git show commit:path shows one snapshot. To see how a file changed between two commits, use git diff with two revision paths:
git diff HEAD~2:README.md HEAD~1:README.mddiff --git a/README.md b/README.md
index 2d00bd5..b6e4dcf 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,3 @@
line one
+
+line twoFor this ordinary single-parent commit, git show HEAD~1 shows the same file change as comparing that commit with its parent (HEAD~2). Merge commits use combined diff formats instead — out of scope here. For arbitrary pairs (not parent/child), git diff is the right tool; see git diff examples for branch and index comparisons.
Tags and low-level objects
Annotated tags
git show on a tag name resolves the tag object first. For an annotated tag you see the tag message, then the tagged commit:
git show v1.0tag v1.0
Tagger: Lab User <lab@golinuxcloud.test>
Date: ...
Release 1.0
commit <hash>
...
diff --git a/app.py b/app.pyLightweight tags (plain refs without a tag object) behave like showing the commit directly. For creating tags, see the git tag tutorial.
Blob objects
Every file revision is stored as a blob. Resolve the blob id for app.py at HEAD:
git rev-parse HEAD:app.py626799f0f85326a8c1fc522db584e86cdfccd51fThat hash is content-addressed — the same file bytes always produce the same blob id. Pass it to git show to print the stored file bytes:
git show "$(git rev-parse HEAD:app.py)"v1git cat-file -p exposes the same data for plumbing scripts; git show formats it for interactive use.
Customize commit formatting
--pretty controls the header when combined with -s (no patch). A one-line summary:
git show -s --pretty=oneline HEAD<hash> Add app.py--pretty=fuller separates author and committer timestamps — useful on imported or amended commits:
git show -s --pretty=fuller HEADcommit <hash>
Author: Lab User <lab@golinuxcloud.test>
AuthorDate: ...
Commit: Lab User <lab@golinuxcloud.test>
CommitDate: ...
Add app.py--abbrev-commit shortens the hash in the header; --no-abbrev-commit forces the full 40-character id.
Quick reference
| Task | Command |
|---|---|
| Latest commit (metadata + patch) | git show or git show HEAD |
| One commit by hash | git show <hash> |
| Parent of HEAD | git show HEAD~1 |
| Header without patch | git show -s <ref> |
| Subject line only | git show -s --format=%s <ref> |
| File list / status | git show --name-only <ref> / --name-status |
| Change summary | git show --stat <ref> |
| File contents at revision | git show <ref>:<path> |
| File diff across two commits | git diff <old>:<path> <new>:<path> |
| Annotated tag | git show <tag> |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
fatal: bad object |
Typo in hash, or object not in this repo | Run git log --oneline or git rev-parse --verify <hash> to confirm the ref |
--format=%s still shows a patch |
git show enables patch output by default |
Add -s / --no-patch: git show -s --format=%s <ref> |
git show on a new repo fails |
No commits yet | Create at least one commit before calling git show |
| Tag shows only a commit, no tag message | Lightweight tag, not annotated | Use git tag -a when you need a message, or git cat-file -p <tag> |
Expected file missing at commit:path |
Path did not exist in that revision | Check spelling and git ls-tree <commit> for paths at that tree |
References
- git-show — official Git documentation
- gitrevisions — revision syntax (
HEAD~1,commit:path, tags)
Summary
git show is the fastest way to read a commit end to end: message, author, date, and the patch Git stored for that revision. On the lab repo, bare git show on HEAD revealed the app.py addition, git show HEAD~1 isolated the README edit, and -s with --format trimmed output when only metadata or the subject line was needed.
The revision:path form (git show HEAD~1:README.md) dumps file contents at a point in history without a checkout. When you need a diff between two arbitrary snapshots of the same path, git diff HEAD~2:README.md HEAD~1:README.md is the correct tool — git show alone only shows one side.
Tags and blob ids work too: annotated tags print the tag message before the commit, and git show <blob> prints raw file bytes. For day-to-day review, pair git show with git log to find hashes and git diff when you are comparing branches or the staging area.

