Theory
Theory: History is a Query over the DAG
git log is not a file. It is a walk of commit objects from one or more tips, filtered by paths, dates, pickaxe, and ranges. Blame is a walk of lines through that DAG.
Invariants
- Reachability:
git log Bshows commits reachable fromBby following parents. - Two-dot
A..B= reachable fromB, not fromA(what a feature branch adds). - Three-dot
A...B= reachable fromAorB, not from the merge base (symmetric difference). A pull-request diff is oftengit diff A...B(merge-base toB). git blameattributes each line of a file to the commit that last touched it;-Calso hunts copies.- Pickaxe
-S/-Gfilters commits by whether a string’s count or a regex’s hunk changed.
A ← B ← C ← G main
↑
D ← E feat
main..feat = D, E
main...feat = G, D, E (both sides since split)
Why this matters on a forge
A PR “files changed” list is this query, computed on the server. Reviewers who can run git log main..HEAD and git diff main...HEAD on Linux are not trapped in the UI.
What can break
- Reading
A..Bas “between A and B inclusive on a line” (it is set difference of reachability). git blameon a file that was reformatted in one giant commit (whitespace;-w).--followonly works when you name one path.
How to read this chapter
Log flags, ranges, show, blame, pickaxe, shortlog, then a lab that finds a line’s origin in desk-api. The last page keeps blame useful across mass reformats with .git-blame-ignore-revs, and follows moved code with -C.