Reading history

Find the commit you are looking for, and read what it actually contains.

03of 16
≈ 11Min read
5Parts

log, and the flags that make it useful

-S is the one people do not know and then use forever: it searches the changes, not the messages. "When did this function get deleted?" is one command.

the ones worth memorising
git log                       # full entries, newest first
git log --oneline             # one line each: short id, refs, subject
git log --oneline --graph --all   # every branch, drawn
git log -3                    # the last three
git log --author=Ulvi
git log --since="2 weeks ago"
git log -- src/app.js         # only commits that touched this file
git log -S "unit_price"       # commits where that text appeared or disappeared

What a commit actually holds

That is the whole thing: a pointer to a tree (the snapshot), zero or more parents, who wrote it and when, who committed it and when, and the message. The id is the SHA-1 of exactly those bytes — change one character of the message and every commit after it gets a new id too.

the object, printed raw
$ git cat-file -p HEAD
tree 4b825dc642cb6eb9a060e54bf8d69288fbee4904
parent 23fd5c39421cd8b4e20350dea0eb1165a25f3e9f
author You <you@example.com> 1700000060 +0000
committer You <you@example.com> 1700000060 +0000

Add the fitting notes
Author and committer are different people

The author wrote the change; the committer created this commit object. They differ when someone applies your patch, and after a rebase — which is why a rebased commit keeps its original author date and gets a new committer date.

Naming a commit without typing forty characters

every one of these is a commit
HEAD            # where you are
HEAD~1          # its parent        (HEAD~ for short)
HEAD~3          # three back, first parent each time
HEAD^2          # the SECOND parent — only a merge has one
main            # the commit that branch points at
832dbe3         # any unambiguous prefix of the id
v1.2            # a tag
and how to check what one means
git rev-parse HEAD~2
git show HEAD~2 --oneline

show and diff

one commit, or the space between two
git show HEAD                 # the commit and its changes
git show 832dbe3:price-list.md   # a file AS IT WAS in that commit

git diff                      # working tree vs index — what is not staged
git diff --staged             # index vs HEAD — what the next commit will contain
git diff main..feature        # everything on feature that is not on main
git diff main...feature        # …since they diverged (the one CI uses)

Who wrote this line, and why

The useful move is blame → take the commit id → git show it. The message and the rest of the change usually explain the line that made no sense, which is the best argument there is for writing decent messages.

blame is not about blame
git blame price-list.md       # every line, with the commit that last touched it
git log -p -- price-list.md   # the whole story of one file, with diffs

Practice