datarekha

Viewing history: log, diff, show

Navigate the commit timeline to find when a line changed, who changed it, and exactly what the change was.

7 min read Beginner Git Lesson 5 of 15

What you'll learn

  • git log and its high-value flags for filtering and formatting
  • Reading a single commit with git show and understanding short SHAs
  • The three faces of git diff: working tree, staged, and commit-to-commit

Before you start

Every commit in a Git repository is a permanent snapshot with a unique identifier called a SHA (or hash) — a 40-character string like a3f8c21d.... You’ll almost always abbreviate it to the first 7 characters, which Git calls a short SHA: a3f8c21. These short SHAs are stable enough for everyday use and appear throughout the tools below.

HEAD is a special pointer that always points to the commit you’re currently on — usually the tip of the branch you have checked out. Think of it as “you are here” on a map.

git log — the commit timeline

Run git log in any repository and you’ll see the full commit history, most recent first. The default output is verbose. These flags turn it into something useful.

One line per commit

git log --oneline
e4b9f31 Fix null-to-empty conversion in user serializer
a3f8c21 Add pagination to /api/users endpoint
71dc409 Bump requests to 2.31.0
c0182de Initial project scaffold

Each line is a short SHA followed by the commit message subject. Fast to scan.

See branches and merges at a glance

git log --graph --oneline --all
* e4b9f31 (HEAD -> main) Fix null-to-empty conversion in user serializer
* a3f8c21 Add pagination to /api/users endpoint
| * 9b3aa17 (origin/feature/dark-mode) Add dark mode toggle
|/
* 71dc409 Bump requests to 2.31.0
* c0182de Initial project scaffold

The --all flag shows every branch, not just the current one. --graph draws the ASCII branch lines.

Limit to the last N commits

git log -n 5 --oneline

Show files changed per commit

git log --stat --oneline
e4b9f31 Fix null-to-empty conversion in user serializer
 src/serializers/user.py | 3 ++-
 tests/test_user_api.py  | 9 +++++++++
 2 files changed, 11 insertions(+), 1 deletion(-)

--stat adds a summary of which files changed and by how many lines. Useful for quickly spotting which commit touched a file you care about.

Show the full diff for every commit

git log -p --oneline

This streams the patch (the actual line-by-line diff) for each commit. Combine with -n 5 to keep output manageable.

Filter by time

git log --since="2 weeks ago" --oneline
git log --since="2026-05-01" --oneline

Filter by author

git log --author="Alice" --oneline

Matches a substring of the author name or email.

Filter by file

git log -- src/serializers/user.py

Only commits that touched that specific file. The -- separator tells Git that what follows is a path, not a branch name.

The commit graph — HEAD and the chain

c01871dca3f8e4b9scaffoldbump depspaginationfix nullHEAD
HEAD points at the latest commit. Each commit knows its parent, forming a chain back through history.

Commits form a linked list pointing backward in time. HEAD tracks whichever commit is current. When you make a new commit, HEAD advances automatically.

git show — inspect one commit

Once git log gives you a SHA, use git show to read that commit in full:

git show e4b9f31
commit e4b9f31d7a2c084f1b3e6d8950c2a1447f83bb91
Author: Alice Chen <alice@example.com>
Date:   Thu Jun 5 14:22:10 2026 +0530

    Fix null-to-empty conversion in user serializer

    The downstream parser treats "" and null differently. Preserve null
    from the DB rather than coercing to empty string.

diff --git a/src/serializers/user.py b/src/serializers/user.py
index 7c3a021..f4d19e8 100644
--- a/src/serializers/user.py
+++ b/src/serializers/user.py
@@ -18,7 +18,7 @@ class UserSerializer:
     def serialize(self, user):
         return {
             "id": user.id,
-            "bio": user.bio or "",
+            "bio": user.bio,
         }

Lines starting with - were removed; lines with + were added. The surrounding unchanged lines give context.

You can also show only one file from a commit:

git show e4b9f31 -- src/serializers/user.py

git diff — three distinct comparisons

git diff means different things depending on what you pass to it. Mixing these up is a common source of confusion.

Working tree vs staging area (what you haven’t staged yet)

git diff

Shows changes in your files that you have not yet staged with git add.

Staging area vs last commit (what will go into your next commit)

git diff --staged

Shows the diff between what’s staged and what was in the last commit. This is exactly what will be recorded when you run git commit.

Commit vs commit

git diff a3f8c21 e4b9f31

Compare any two commits directly. Useful for reviewing what changed across a range of work. You can also use branch names:

git diff main feature/dark-mode

Or compare a commit to HEAD:

git diff a3f8c21 HEAD

git blame — who last touched each line

git blame annotates every line of a file with the commit SHA, author, and date that last modified that line:

git blame src/serializers/user.py
c0182de3 (Bob Kumar  2026-04-10 09:14:02 +0530 14)     def serialize(self, user):
c0182de3 (Bob Kumar  2026-04-10 09:14:02 +0530 15)         return {
c0182de3 (Bob Kumar  2026-04-10 09:14:02 +0530 16)             "id": user.id,
e4b9f31d (Alice Chen 2026-06-05 14:22:10 +0530 17)             "bio": user.bio,
c0182de3 (Bob Kumar  2026-04-10 09:14:02 +0530 18)         }

Line 17 was last changed by Alice in commit e4b9f31d — and you now know exactly which commit to git show to read the full explanation. This is the answer to “who is responsible for this line and why?”

Putting it together — the debugging workflow

When something breaks:

  1. git log --oneline -- path/to/file — find which commits touched that file.
  2. git show <sha> — read the full diff and commit message for the suspicious commit.
  3. git blame path/to/file — if you’re not sure which commit, blame shows exactly which line came from where.
  4. git diff <old-sha> <new-sha> — compare two points in time if you want to see the cumulative change across multiple commits.

Quick check

Quick check

0/3
Q1You run `git diff` after editing a file and see no output, even though you made changes. What's the most likely explanation?
Q2Which command shows you the full diff (added and removed lines) for a single commit `7fa2c09`?
Q3A bug was introduced somewhere in the last month in `src/api/payments.py`. Which command gives you the most targeted starting point?

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Explore further

Cheat sheets

Related lessons

Skip to content