Chapter 05Lesson 04~90 minutes

Commits, Diffs, History Inspection, Revision Ranges, and Message Discipline: Diagnostics, Failure Modes, Security, and Performance

Diagnose misleading history and diff views safely: dotted-range mistakes, patch-versus-object confusion, accidental commit scope, revision/path ambiguity, hidden history from filters, and prohibited published-history rewrites.

DiagnosticsHistory filtersPublished historySafety

Learning objectives

  • Apply an evidence-first sequence before changing refs or commits.
  • Diagnose A..B versus A...B mistakes separately for traversal and diff commands.
  • Distinguish computed patch output from stored commit-object content.
  • Prevent accidental mixing of staged and unstaged tracked changes, including commit -a behavior.
  • Recognize when filters or history simplification hide commits and when published-history policy forbids amend/rewrite.

1. Diagnostic sequence — preserve the graph before changing it

  1. Preserve evidence: exact command, current branch/OID, status, relevant refs.
  2. Inspect working tree/index: ordinary and staged diff.
  3. Inspect graph: unfiltered decorated log/rev-list before adding filters.
  4. Inspect configuration: aliases, pretty formats, mailmap, diff settings only when output differences point there.
  5. Identify the layer: object, ref, commit set, snapshot comparison, path filter, or presentation.
  6. Choose the least destructive correction and verify the question again.

2. Failure mode — reading A..B and A...B as interchangeable

Suppose two branches diverged. This pair does not answer the same question:

git log --oneline A..B
git log --left-right --oneline A...B

The first selects B-only reachable commits. The second selects commits unique to either side. If a reviewer says “show me everything different between the branches,” first clarify whether they mean unique commits on both sides or snapshot content difference.

3. Intentionally broken expectation — git diff A...B is not a symmetric patch set

A learner runs:

git diff trunk...feature

and expects it to include both trunk-only and feature-only changes because git log trunk...feature used symmetric difference. That expectation is wrong. In git diff, the three-dot form compares the merge base against B.

Repair the question explicitly:

# Endpoint snapshots
git diff trunk feature

# Feature-side changes since divergence
git diff trunk...feature

# Commit sets unique to both sides
git rev-list --left-right trunk...feature

4. Failure mode — treating formatted patch output as the commit object

git show HEAD
git cat-file -p HEAD
git show --no-patch --format=raw HEAD

The first command normally shows commit metadata/message plus a computed diff. cat-file -p exposes the commit object's stored fields. If a diff algorithm or context-line setting changes the patch view, the commit object does not change.

5. Failure mode — staged and unstaged changes accidentally mixed into one commit

Before committing, always ask which paths/hunks are actually in the index:

git status --short
git diff
git diff --staged
git commit --dry-run

A particularly dangerous convenience is git commit -a or git commit -am: Git automatically stages modifications/deletions of already-tracked files for that commit. It does not add new untracked files, but it can include tracked working-tree changes you intentionally left unstaged.

Use -a only when that behavior is exactly your intention. It is not a substitute for reviewing the index.

6. Failure mode — a revision and path share the same name

With a branch named release and a path named release, a command such as git log release is naturally interpreted as a revision traversal.

git log --oneline release
git log --oneline -- release
git diff HEAD -- release

The standalone -- marks the path boundary. If a token begins with a dash, the boundary also prevents it being treated as another option after option parsing is complete.

7. Failure mode — history filters hide the commit you are looking for

History output is the result of selection, simplification, ordering, and formatting. These commands can legitimately show different sets:

git log --oneline --since='2 weeks ago'
git log --oneline --grep='timeout'
git log --oneline -- src/service.py
git log --full-history --oneline -- src/service.py

If a known commit “disappears,” remove filters one by one and inspect the full decorated graph. Path-limited history can simplify merges; date/message filters can exclude relevant commits by design.

8. Failure mode — rewriting published history just to improve presentation

git commit --amend creates a replacement commit. Even a message-only amendment changes the commit object/OID. If the old commit has already been shared and project policy forbids rewriting published history, a prettier message is not sufficient justification.

Published-history boundary: do not amend/rebase/force-update shared commits merely to improve wording. Add a follow-up correction, document context in the review/issue system, or follow the repository's coordinated rewrite policy if the defect genuinely requires it.

9. Security concerns specific to history and diff views

  • Commit messages are stored in history; do not paste tokens, private URLs, passwords, or secret incident payloads into them.
  • git show/git diff can expose secrets present in historical file content. Sanitize logs before posting them to support channels.
  • Changing a message or diff display does not remove secret content from old objects. Rotate/revoke leaked credentials first; history-removal is a separate Chapter 21 procedure.

10. Performance without sacrificing correctness

Limit output intentionally: --no-patch when only metadata is needed, --max-count for bounded recent views, --format for machine reports, or path filters when the question truly concerns one path. But performance filters also narrow evidence. During incident forensics, preserve an unfiltered baseline command in the report so another engineer can reproduce how the narrower result was derived.

11. Red-zone operations

Do not use history-rewriting or destructive cleanup as first-response diagnostics: git commit --amend, rebase, destructive reset, force push, reflog expiry, pruning, or secret-rewrite tools all change history or recovery options. Diagnose with read-only log/show/rev-list/diff/status commands first.

12. Symptom → likely misunderstanding

Symptom Likely issue First evidence
Three-dot log has commits from both sides Symmetric set semantics rev-list --left-right A...B
Three-dot diff shows only feature-side change Diff merge-base semantics merge-base + endpoint diffs
Commit “contains a patch” that changed after config Patch is computed presentation cat-file -p COMMIT
Unexpected tracked changes committed -a or broad staging status + staged diff + reflog/log
Path history misses known commit Filter/history simplification unfiltered graph + --full-history

13. Knowledge check

Question 1. A reviewer asks for “commits unique to either branch.” Which family of command answers that?

Question 2. Why can a diff look different after changing diff.algorithm even though the commit OIDs are unchanged?

Question 3. What hidden behavior makes git commit -am "msg" risky when you intentionally left a tracked file unstaged?

Question 4. A path-limited log misses a merge-related commit. What should you do before assuming history is lost?

Question 5. Why can a message-only amend be unsafe on a shared branch?

14. Summary

History diagnostics start by separating commit sets, snapshot comparisons, object content, filters, and presentation. Most confusing log/diff output can be explained without changing a single ref; preserving that discipline prevents cosmetic problems from becoming history-rewrite incidents.

Next

Checkpoint reviewable history—and rewrite only unpublished local work

Lesson 5 creates one intentionally poor local commit boundary, splits it safely before publication, amends a local message to explain why, and produces a compact reproducible history report.

Authoritative references

 gitrevisions
 git-diff
 git-log
 git-commit

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.