Use git show to inspect commits, files, tags and notes
You will finish with a small set of safe git show commands for examining a commit, a file as it existed in a revision, an annotated tag, and commit notes. The commands only read repository objects. Allow about ten minutes, assuming you are already in the right working tree.
The route
Jump straight to the step you need, or tick off Done means at the end.
This guide describes Git 2.43.0, supplied here by Ubuntu packages git and git-man version 1:2.43.0-1ubuntu7.3. Later Git versions can add or adjust details, so use git show --help on the machine you are investigating when exact output matters.
1. Check the repository and command
Run this from the working tree whose objects you want to inspect. It is an ordinary, read-only check and does not need elevated privileges:
$ git --version
git version 2.43.0
$ git rev-parse --show-toplevel
/path/to/project
$ git show --help
The synopsis is git show [options] [object...]. If you omit the object, Git uses HEAD. That default is convenient, but it is also a common distraction trap: when someone says "show the last commit", first confirm that HEAD is the branch and commit you mean.
Checkpoint
You are inside the intended repository, and git --version identifies the Git installation whose behaviour you are checking.
2. Read the current commit
With no object or extra formatting option, git show displays the commit message and its textual diff. It also shows default commit notes when no pretty-format, format or oneline option is supplied:
$ git show HEAD
commit 0123456789abcdef0123456789abcdef01234567
Author: Example Person <[email protected]>
Date: Mon Sep 23 10:15:00 2024 +0100
Update the service configuration
diff --git a/config/service.conf b/config/service.conf
...
The hash, author, date, message and diff will be different in your repository. The useful result is the patch that the selected commit introduced. A merge commit is presented in a combined format, so it may not look like a normal one-parent patch.
To see only the commit header and message, suppress the diff:
$ git show --no-patch HEAD
commit 0123456789abcdef0123456789abcdef01234567
Author: Example Person <[email protected]>
Date: Mon Sep 23 10:15:00 2024 +0100
Update the service configuration
--no-patch is an alias for the diff-suppression behaviour commonly used with git show. It does not hide the commit message.
3. Make a compact commit record
Use --oneline when you need one readable line for a commit rather than its full message and patch:
$ git show --oneline --no-patch HEAD
0123456 Update the service configuration
This option combines the oneline pretty format with an abbreviated commit name. The abbreviation is chosen to name the object uniquely at the time of display, so do not treat it as a fixed length identifier. Use --no-abbrev-commit when a full 40-character object name is required.
For a stable, script-friendly selection of fields, provide a format explicitly:
$ git show -s --format='%H %an %as %s' HEAD
0123456789abcdef0123456789abcdef01234567 Example Person 2024-09-23 Update the service configuration
Here -s suppresses the patch, while %H, %an, %as and %s expand to the full hash, author name, short author date and subject. Quote the format so the shell passes the percent placeholders unchanged.
4. Inspect one file at a revision
A revision followed by a colon and a path asks Git for the contents of that path in the revision. This reads the committed snapshot; it does not read your working copy and it does not restore anything:
$ git show HEAD:config/service.conf
listen = 127.0.0.1:8080
log_level = info
Use a commit, tag or another valid revision in place of HEAD. The path is relative to the repository root. If the path contains spaces or shell metacharacters, quote the complete revision-and-path expression:
$ git show 'v2.4:docs/Release notes.txt'
Do not confuse this with git show HEAD -- config/service.conf. The latter selects a commit diff and limits that diff to a path; the colon form prints the file contents from the tree object.
Checkpoint
Compare the historical content without changing the checkout:
$ git show HEAD:config/service.conf > /tmp/service.conf.from-head
$ cmp -- /tmp/service.conf.from-head config/service.conf
$ printf 'cmp status: %s\n' "$?"
cmp status: 1
A status of 0 means the files are identical. A status of 1 means they differ. The redirection creates a temporary copy outside the repository; it does not modify the tracked file. If the destination already matters, choose a new temporary name rather than overwriting it.
5. Examine an annotated tag
When the object is an annotated tag, git show prints the tag message followed by the referenced object. This is useful for checking what a release tag actually points to:
$ git show --no-patch v2.4
tag v2.4
Tagger: Example Person <[email protected]>
Date: Mon Sep 23 10:15:00 2024 +0100
Release 2.4
commit 0123456789abcdef0123456789abcdef01234567
Author: Example Person <[email protected]>
...
Tag names and output are repository-specific. For a lightweight tag, Git resolves the name directly to its target, so there is no separate tag message to display. If you need to confirm the object type before interpreting the output, use:
$ git cat-file -t v2.4
tag
git cat-file is a separate read-only plumbing command. It is not an alternative spelling for git show, but it removes ambiguity when tags and commits have similar names.
6. Control notes and diff size
Commit notes can add review or deployment context that is not part of the commit object. Because notes are shown by default in the ordinary format, use --no-notes when you need the commit message and patch without them:
$ git show --no-notes HEAD
To request a particular notes ref, use --notes=REF. The ref may be written as a full refs/notes/... name or as the shorter name accepted by Git:
$ git show --notes=review --no-patch HEAD
When a patch is too large to review in one terminal, ask for its summary:
$ git show --stat --format=short HEAD
commit 0123456789abcdef0123456789abcdef01234567
Author: Example Person <[email protected]>
Update the service configuration
config/service.conf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
A summary is not a substitute for reading the diff. It tells you which paths and line counts are involved, not whether the change is safe or correct.
7. Diagnose the likely mistakes
If Git says it cannot resolve an object, check the revision spelling and the refs available locally:
$ git show 'REPLACE_WITH_A_REAL_REVISION'
fatal: ambiguous argument 'REPLACE_WITH_A_REAL_REVISION': unknown revision or path not in the working tree.
$ git show-ref --heads --tags
$ git log --oneline --all --decorate -n 10
Replace the placeholder with a real commit, branch, tag or other revision. Fetching a missing remote object may change local repository state, so it is outside this inspection workflow and should be a deliberate separate action.
If a colon-form path fails, check whether the path existed in that revision. A file renamed or added later will not exist in an older tree. Use git ls-tree REVISION to inspect the names stored in that tree, then retry with the exact path.
If output contains unexpected colours or is hard to parse, use an explicit format and send output to a file or pipe. Avoid forcing terminal colour in scripts. If you ask git show to verify a signed commit with --show-signature, Git passes the signature to GnuPG and displays its result; treat that as security-sensitive evidence and check the signer identity and trust policy rather than trusting a green-looking line.
None of the examples above needs sudo. Do not elevate merely because a repository contains files owned by another account. First fix the access boundary or ask the repository owner. Running inspection commands as root can also create root-owned files if you redirect output into the working tree.
Done means
- You confirmed the repository and installed Git version before interpreting output.
- You used an explicit revision when
HEADcould be ambiguous. - You can distinguish a commit diff from a file snapshot selected with
REVISION:path. - You know that ordinary output can include commit notes, and can suppress or select them.
- You used
--statfor triage and a full diff for actual review. - You did not modify history, the index, the checkout or repository configuration.