Resources / Guide
Reading git history: log, diff & blame
Most of git is about making history. A big part of the day-to-day value is reading it — what changed, when, and who did it. Four read-only commands turn a repo from an opaque pile of files into the most honest documentation a project has.
git log — what happened, and when
git log lists commits, newest first: the message, author, date, and a unique ID (the hash). On its own it's verbose, so the version actually worth memorizing is the compact one:
git log --oneline
That gives you one line per commit — short hash and message — which is usually all you need to get your bearings:
a1b2c3d Fix null reference when order has no line items
9f8e7d6 Add export button to orders grid
4c5b6a7 Bump dependency versions
A few additions that earn their keep:
git log --oneline --graph # draw the branch/merge structure
git log --oneline -10 # just the last 10
git log --oneline -- Program.cs # only commits that touched one file
git log --author="Sam" # only one person's commits
git log --since="2 weeks ago" # recent history
That last group is how you answer real questions: "what's changed in this file lately?", "what did I do last week?", "when did this dependency get bumped?". The -- <file> form is especially handy — it filters the whole history down to a single file's story.
git diff — what actually changed
A log tells you that something changed; git diff shows you what. With no arguments, it shows the changes in your working directory that you haven't staged yet:
git diff
Lines starting - were removed, lines starting + were added. Useful variants:
git diff --staged # what you've staged, ready to commit
git diff main # how your branch differs from main
git diff a1b2c3d 9f8e7d6 # the difference between two commits
git diff --staged is the one to build a habit around: run it right before you commit to read exactly what you're about to save. It catches the stray debug line, the accidentally-committed secret, the file you didn't mean to touch — the things that are annoying to fix after they're in history.
git show — one commit, in full
When git log points you at an interesting commit, git show opens it: the message plus the full diff of what it changed.
git show a1b2c3d
This is how you inspect a single change end to end — "what exactly did that bug fix touch?" — without digging through the whole history around it.
git blame — who last touched each line
git blame answers "who wrote this line, and in which commit?" by annotating a file line-by-line with the last commit that changed it:
git blame Program.cs
Each line gets a short hash, the author, the date, and the line itself. Despite the name, it's rarely about assigning fault — it's about context. You find a weird-looking line, blame tells you which commit introduced it, and git show <that hash> tells you why (the commit message and everything else that changed alongside it). That chain — blame to find the commit, show to read the reasoning — is one of the most useful moves in git, and it's how a good commit message written months ago saves someone an hour today.
Most editors and git hosts wrap blame in a nicer UI (hover a line, see the commit), but the command is always there when you want it.
Putting it together
These four commands form a little investigation loop. git log --oneline to scan what's happened, git diff to see uncommitted changes, git show to open a specific commit, and git blame to trace a particular line back to the decision that created it. None of them change anything — they're all read-only — so you can run them freely while finding your way around a codebase. The more comfortable you get reading history, the more a repo stops being a black box.
Inherited a codebase with no documentation?
Sometimes the git history is the only spec there is. I dig into unfamiliar .NET systems, map how they actually work, and get them moving again. If that's where you are, let's talk.
Work with me