Course outline

Git and GitHub / Basic: the local Git model / Lesson 3

History, diffs, and evidence-based inspection

Read snapshots and ancestry without assuming a displayed patch tells the entire history of a change.

About 4 min readContent reviewed
On this page

Lesson goals

  • Navigate commits and select precise comparison ranges.
  • Use paths and search filters with awareness of their limits.

Read the graph before the patch

git log starts from selected references and walks reachable history. The displayed order and formatting are a view over a graph, not proof that development happened in one linear sequence. Merge commits can have multiple parents, and branch decorations show current reference names rather than permanent ownership of commits. Begin with a bounded graph view, identify the relevant commit, then inspect its metadata and patch. Avoid equating the latest timestamp with ancestry: author dates, committer dates, and parent relationships are different information and can diverge during rebasing or imported history.

Inspect a bounded local history

In a temporary lab with commits Create notebook and Update notebook, a subject-only log produces stable text without predicting object ids or dates. Add graph and decorations when you need branch context, and use --all only when the wider reference set matters. A path-limited log can simplify history and omit commits irrelevant to that view; it is not necessarily the full explanation of a merge. Keep the original unfiltered graph available when investigating surprising ancestry. Inspection commands are read-only, but their output can still contain private messages or paths that should not be shared indiscriminately.

bash Read subjects and then graph context
git log -2 --format=%s
git log --graph --oneline --decorate -8

The first command prints Update notebook followed by Create notebook under the stated two-commit setup. The graph command includes generated ids and current refs, so its exact rendering depends on the lab graph and is not fixed here.

Distinguish log ranges from diff comparisons

For revision walking, A..B selects commits reachable from B but not from A. A...B selects the symmetric difference, useful with left-right output. For git diff, A B compares the two endpoint trees, while A...B compares the merge base of A and B with B. The same punctuation therefore serves related but different purposes across commands. A pull-request comparison often resembles a merge-base view rather than a raw comparison of current branch tips. State the question first: which commits are unique, or which content changed from a chosen base?

Read an earlier file without switching

git show can inspect a file stored in a selected commit without changing the working tree. This is useful when checking a previous configuration or comparing behavior with a known revision. The example assumes HEAD is the second lab commit and HEAD~1 is its first-parent predecessor. Parent notation depends on graph structure; for a merge, ~ follows first parents while ^ can select a specific parent. Quote revision expressions where the shell needs it and keep -- before path filters when commands support that separation. Do not modify current files merely to read historical content.

bash Inspect historical content and changed path names
git show HEAD~1:notes.txt
git diff --name-only HEAD~1 HEAD -- notes.txt

With the first commit containing A local notebook and the second changing notes.txt, show prints that original line and the diff lists notes.txt. These commands inspect committed content and do not stage or restore anything.

Use search as a starting point for explanation

Message search, path history, and content-change searches help narrow an investigation, but each has a scope. git log -S searches changes in occurrence counts of a string, while -G matches added or removed lines by regular expression. A rename is inferred from similarity under chosen options rather than stored as an eternal file identity. blame identifies commits associated with lines under its traversal rules, not the person responsible for every later consequence. Read surrounding code, tests, and review context before turning historical attribution into a conclusion about intent or correctness.

Common errors and fixes

A range shows unexpected commits

Why it happens
Endpoint diff semantics were confused with revision walking.
How to fix it
State whether the question concerns commits or tree content.
Prevent it next time
Check the command-specific meaning of two and three dots.

A file appears to have no earlier history

Why it happens
Path filtering or rename inference limits the view.
How to fix it
Inspect the wider graph and appropriate rename-aware history.
Prevent it next time
Keep filtered views separate from full-history claims.

A timestamp is used to infer ancestry

Why it happens
Metadata order is mistaken for parent relationships.
How to fix it
Inspect parent links and the graph directly.
Prevent it next time
Distinguish author date, committer date, and ancestry.

Check your understanding

1. You need changes introduced by a topic since its common base with main. Which comparison matches?

Show worked solution

A three-dot diff from main to the topic compares their merge base with the topic tip. Verify the intended base and branch names first. A two-endpoint diff instead includes differences caused by main’s independent progress.

2. A blame result points to a formatting commit. How should investigation continue?

Show worked solution

Inspect earlier relevant history using suitable whitespace or movement options where appropriate, then read the original behavior change and tests. Line attribution is an investigative clue and does not establish causation or intent by itself.

Key takeaways

  • History views answer bounded questions about a graph.
  • Range punctuation has command-specific semantics.
  • Inspect historical content without disturbing current work.

Official references