Chapter 15Lesson 04~110 minutes

Advanced Revision Selection, Log Search, Path History, and Ancestry Analysis: Diagnostics, Failure Modes, Security, and Performance

Diagnose semantically incorrect history queries: three-dot log/diff confusion, path simplification, --follow limits, shell expansion, ambiguous short IDs, misleading copied commands, and display-order misconceptions.

DiagnosticsThree-dotSimplificationShell safety

Learning objectives

  • Preserve query evidence and resolve endpoints before changing the repository.
  • Diagnose command-specific three-dot semantics with rev-list and merge-base.
  • Recognize path-history simplification and --follow limitations.
  • Protect revision/pathspec syntax from shell expansion and ambiguous abbreviations.
  • Cross-check human log answers using stable plumbing and object-level commands.

1. Diagnostic sequence for a suspicious history answer

  1. Preserve evidence: exact command, shell, Git version, current refs/OIDs, clone depth, and output.
  2. Resolve every revision token with rev-parse/show-ref.
  3. Identify the query layer: commit set, tree diff, pathspec, history simplification, ordering, or display.
  4. Restate the question in plain language and construct the smallest matching expression.
  5. Cross-check with an independent command such as rev-list, merge-base, or show.

2. Capture a reproducible evidence bundle

git --version
git status --short --branch
git rev-parse HEAD
git show-ref --heads --tags
git rev-parse --is-shallow-repository
git config --list --show-origin --show-scope
git log --graph --decorate --oneline --all --max-count=40

If the repository is shallow, partial, or missing refs, fix data availability before arguing about revision syntax.

3. Intentionally broken assumption — “three-dot always means symmetric difference”

git log --oneline A...B
git diff --stat A...B

The first command walks the symmetric-difference commit set. The second compares the merge-base tree to B. A user may see several commits in the log but only one file in the diff and think Git is inconsistent.

Repair the mental model

git merge-base A B
git rev-list --left-right A...B
git diff "$(git merge-base A B)" B

The final diff states the tree comparison explicitly. The original commands were both valid; the incorrect assumption was treating command-specific syntax as universal semantics.

4. Failure mode — path history simplification hides a merge-parent contribution

A default path-limited log can prune a side branch when the selected path is TREESAME relative to a parent or when topology is simplified. Compare progressively:

git log --graph --oneline -- path/to/file
git log --full-history --graph --oneline -- path/to/file
git log --full-history --simplify-merges --graph --oneline -- path/to/file
git show --cc <merge-oid> -- path/to/file

If an audit asks whether a merge parent touched the path, use the fuller traversal and inspect the merge/diffs directly rather than trusting one simplified display.

5. Failure mode — --follow treated as arbitrary lineage reconstruction

--follow is defined for a single file and relies on rename detection. It is not designed to infer every history through directory-wide refactors, copies, split files, generated files, or complex merge topology.

git log --follow --name-status -- path/to/file
git log --all --name-status -- path/to/file
git show <known-commit>^:<old-path>
git show <known-commit>:<new-path>

When lineage is ambiguous, identify the suspected transition commit and compare exact tree paths/content.

6. Failure mode — the shell expands your pathspec before Git sees it

Suppose you intend Git to search all Markdown files recursively:

git log --oneline -- *.md

In a POSIX shell, *.md may expand immediately to files in the current directory. Git then receives a list of literal paths, not your intended pattern.

Repair

git log --oneline -- ':(glob)**/*.md'

Single quotes protect the pathspec in common POSIX shells and PowerShell. If your shell differs, use its documented literal-argument quoting rules.

7. Failure mode — revision selector characters are interpreted by the shell

Reflog selectors and parent expressions contain braces/carets that some shells treat specially. Prefer quoting in portable examples:

git rev-parse 'trunk@{1}'
git rev-parse 'HEAD^2'
git rev-parse 'HEAD~3'

8. Failure mode — a short object prefix becomes ambiguous

A prefix that once resolved can fail after the repository gains more objects:

git rev-parse deadbee

A typical error reports an ambiguous or unknown revision. Do not “fix” automation by guessing a longer prefix from human output. Store full IDs in durable records and let rev-parse --short choose display abbreviations for humans.

9. Failure mode — copying a log command without knowing its commit set

Consider:

git log --all --since='7 days ago' --first-parent -- services/api

This mixes multiple roots (--all), a time filter, a traversal rule, and a path filter. Before reusing it, translate each part into a sentence. For a release audit, a precise range such as v2.4.0..v2.5.0 may be safer than “whatever refs existed in the last seven days.”

10. Failure mode — confusing display order with causal order

Commit timestamps can be skewed. Default date-oriented display does not define ancestry. Use topology/parent relationships to answer causality:

git log --topo-order --graph --oneline A..B
git merge-base --is-ancestor A B
echo $?

PowerShell users can inspect $LASTEXITCODE instead of $?. Exit code 0 means A is an ancestor of B.

11. Security relevance — reports can leak paths and commit metadata

History reports may expose internal branch names, file paths, author identities, incident references, or historical secret-bearing filenames even when file content is not printed. Treat exported audit reports as data with an access policy. This is not a reason to avoid history analysis; it is a reason to scope and store reports deliberately.

12. Performance relevance — path and rename searches can be expensive

--follow, rename detection, --all, full-history traversal, and broad pathspecs can walk substantial history. First verify the query's correctness, then narrow refs/ranges/paths. Commit-graph and maintenance structures from Chapter 22 can accelerate many history walks, but they do not change semantic membership.

13. No destructive command is required to fix a history query

Revision-analysis mistakes should normally be corrected with read-only commands. Do not rewrite history, delete refs, expire reflogs, prune objects, or reset work merely because a report looks wrong. Preserve the graph and fix the query first.

14. Symptom → likely semantic mismatch → verification

Symptom Likely cause Cross-check
Three-dot log and diff “disagree” Different command semantics rev-list --left-right + merge-base
Merge-side change absent in path log History simplification --full-history + inspect merge
Rename trace stops --follow limitation/heuristic Exact show commit:path around transition
Pattern finds wrong files Shell expansion/pathspec mismatch Quote explicit pathspec magic
Short ID fails later Prefix no longer unique Use stored full ID

15. Knowledge check

Question 1. Why can git log A...B and git diff A...B legitimately produce very different-looking answers?

Question 2. What should you try when a path-limited log seems to omit relevant merge history?

Question 3. Why quote Git pathspecs?

Question 4. What is the safe response to an ambiguous abbreviated object ID?

Question 5. Do you need destructive Git commands to repair a history-analysis query?

16. Summary

History-analysis failures are usually semantic mismatches, not damaged repositories. Resolve endpoints, distinguish commit sets from tree diffs, control simplification, treat rename tracing as heuristic, protect arguments from the shell, and store full IDs in durable reports.

Next

Checkpoint five real audit questions and save two report formats

Lesson 5 builds a deployment graph, verifies revision expressions, and saves both human-readable and machine-readable provenance outputs.

Authoritative references

 gitrevisions
 git-log
 git-diff
 gitglossary pathspec

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.