git
version control
file changes
git diff
software development

See changes to a specific file using git

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

When you work on a project with many collaborators, understanding exactly what changed in a single file — and when — is a skill you will use every day. Git provides several commands that let you inspect a file's history from different angles: a high-level list of commits, a line-by-line diff, an annotation of who wrote each line, and more. Knowing which command to reach for saves time and helps you debug issues faster.

View Commit History for a File

The most basic way to see what happened to a file is git log with the file path. This shows every commit that touched the file, in reverse chronological order.

bash
git log -- src/utils/auth.ts

The double dash (--) tells Git that everything after it is a file path, not a branch name. This matters when a file and a branch share the same name.

Add --oneline for a compact view:

bash
git log --oneline -- src/utils/auth.ts

To follow the file across renames, add --follow:

bash
git log --follow -- src/utils/auth.ts

Without --follow, Git stops showing history at the point the file was renamed. With it, Git traces the file back to its original name.

View the Actual Diff per Commit

Adding the -p (patch) flag to git log shows the full diff for each commit, limited to the file you specify.

bash
git log -p -- src/utils/auth.ts

This is equivalent to running git diff between every pair of consecutive commits, but only for that one file. It is extremely useful when you want to understand how a file evolved over time.

You can combine -p with other log flags:

bash
1# Show only the last 3 changes with diffs
2git log -p -3 -- src/utils/auth.ts
3
4# Show diffs with stat summary
5git log -p --stat -- src/utils/auth.ts

Compare Working Copy or Staged Changes

git diff without a commit reference compares your working directory against the staging area (index). To limit it to a single file:

bash
1# Unstaged changes to the file
2git diff src/utils/auth.ts
3
4# Staged changes (what will be committed)
5git diff --cached src/utils/auth.ts
6
7# Compare working directory against a specific commit
8git diff HEAD~3 -- src/utils/auth.ts
9
10# Compare the file between two branches
11git diff main feature-branch -- src/utils/auth.ts

Each variant answers a slightly different question: "What have I changed but not staged?", "What have I staged?", "How does my file differ from three commits ago?", or "How does this file differ between branches?"

Annotate Every Line with git blame

git blame shows who last modified each line of a file, along with the commit hash and timestamp.

bash
git blame src/utils/auth.ts

Sample output:

text
1a1b2c3d4 (Alice   2025-06-10 14:22:01 +0000  1) import { verify } from 'jsonwebtoken';
2e5f6a7b8 (Bob     2025-07-03 09:15:44 +0000  2) import { db } from '../database';
3a1b2c3d4 (Alice   2025-06-10 14:22:01 +0000  3)
4f9d8c7b6 (Charlie 2025-08-21 16:08:12 +0000  4) export async function authenticate(token: string) {

To dig deeper into a specific line range:

bash
git blame -L 10,25 src/utils/auth.ts

This limits the output to lines 10 through 25, which is helpful in large files where scrolling through the entire blame output is impractical.

Show a File at a Specific Commit

Sometimes you do not want a diff — you want to see the entire file as it existed at a particular point in time. Use git show with the commit:path syntax:

bash
git show abc1234:src/utils/auth.ts

You can redirect the output to a temporary file if you want to compare it side by side in an editor:

bash
git show abc1234:src/utils/auth.ts > /tmp/auth_old.ts

This is particularly useful during code reviews or when you need to restore a deleted function from a previous version of the file.

Common Pitfalls

  • Omitting the -- separator before the file path, which can cause Git to interpret the path as a branch name and produce confusing results or errors.
  • Forgetting to use --follow when inspecting history for a file that was renamed, so the log appears to start at the rename commit instead of going back to the original creation.
  • Confusing git diff (unstaged changes) with git diff --cached (staged changes), which leads to thinking changes are missing when they have actually already been added to the index.
  • Running git blame on a file with auto-formatted changes and seeing the formatter's commit on every line instead of the meaningful change, which can be avoided with git blame -w to ignore whitespace.
  • Using git log -p on a file with a very long history without limiting the number of commits (for example with -5), resulting in an overwhelming amount of output that is hard to navigate.

Summary

  • Use git log -- file to see a compact list of every commit that touched a file, and add --follow to trace history across renames.
  • Use git log -p -- file to see the full diff for each commit, which reveals exactly what changed and when.
  • Use git diff to compare the working copy, staged changes, or two branches for a specific file.
  • Use git blame to find out who last modified each line of a file and when, which is invaluable for tracking down the origin of a bug.
  • Use git show commit:file to view the entire contents of a file as it existed at a specific commit, without any diff formatting.

Related reading
Free course
Beginner
7 lessons
2 hours
Tackling System Design Interview Problems

A short course that equips you with the skills to approach system design interviews methodically.

Start the free course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.