Git
Version Control
File Tracking
Code Management
Software Development

GIT list of new/modified/deleted files

Interview Questions practice on Codemia

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

Browse interview questions

Introduction

Listing new, modified, and deleted files in Git sounds simple until you realize Git keeps multiple states at the same time. A file can be modified but unstaged, staged with a different change, or untracked and not yet part of history. The key to accurate output is choosing the exact comparison you want and using commands designed for that state instead of hoping one command means "everything."

Understand the Three Core States

Before running commands, map your question to one of these states:

  • Working tree: files currently on disk.
  • Index: what is staged for the next commit.
  • HEAD: the latest commit on the current branch.

If you skip this step, you get confusing results, especially in automation. For example, git diff compares working tree to index by default, so it does not include staged changes. git diff --cached compares index to HEAD, so it does not include unstaged edits.

A quick state review:

bash
git status --short
git diff --name-status
git diff --cached --name-status

Use git status --short for a compact human overview. The two-column status markers show staged and unstaged state separately.

Get New, Modified, and Deleted Files Reliably

If you need all change types, use --name-status with the right comparison target.

bash
1# Unstaged changes only
2git diff --name-status
3
4# Staged changes only
5git diff --cached --name-status
6
7# Changes between current branch and another ref
8git diff --name-status main..feature/login

Status codes you usually care about:

  • A added
  • M modified
  • D deleted
  • R renamed
  • C copied

When generating release checks, do not ignore renames by default. A rename may be represented as delete plus add if rename detection is disabled or thresholds are not met.

You can filter by type directly:

bash
1# Added only
2git diff --name-only --diff-filter=A
3
4# Modified only
5git diff --cached --name-only --diff-filter=M
6
7# Deleted only
8git diff --name-only --diff-filter=D

Include Untracked Files Correctly

git diff does not show untracked files. If your definition of new files includes untracked paths, use status output.

bash
# Porcelain format is stable for parsing
git status --porcelain

In porcelain output, lines beginning with ?? are untracked files. For scripts, this is safer than parsing human-readable git status output.

Example parse logic in shell:

bash
1#!/usr/bin/env bash
2set -euo pipefail
3
4while IFS= read -r line; do
5  code="${line:0:2}"
6  path="${line:3}"
7
8  case "$code" in
9    "??") printf "untracked\t%s\n" "$path" ;;
10    " M"|"M "|"MM") printf "modified\t%s\n" "$path" ;;
11    " D"|"D "|"DD") printf "deleted\t%s\n" "$path" ;;
12    " A"|"A ") printf "added\t%s\n" "$path" ;;
13  esac
14done < <(git status --porcelain)

This approach keeps source state explicit and works well in CI hooks.

If filenames can contain spaces or unusual characters, prefer null-delimited output modes where available and parse carefully. Path handling bugs are common in repository automation even when the Git command itself is correct.

Compare Against a Commit, Branch, or Tag

Sometimes you need a file list for deployment between two refs, not local edits.

bash
1# Files changed between two tags
2git diff --name-status v1.8.0..v1.9.0
3
4# Files changed since merge-base with main
5git diff --name-status $(git merge-base main HEAD)..HEAD

Use merge-base comparison for feature branch reporting. It avoids noise from unrelated commits pulled into the branch after rebases or merges.

Practical Workflow Pattern

A stable workflow for teams is:

  1. Use git status --short for quick local visibility.
  2. Use git diff --name-status for unstaged checks.
  3. Use git diff --cached --name-status before commit.
  4. Use ref-to-ref git diff for release or deployment audits.

That pattern prevents accidental omissions and makes script behavior predictable.

Common Pitfalls

A frequent mistake is assuming one command can represent all states in one accurate list. Another is forgetting untracked files when checking what is new, because diff commands do not show them. Teams also break automation by parsing localized or human-formatted status output instead of porcelain output. Rename handling is another source of confusion when audits treat rename as delete plus add. Finally, running commands from nested paths can produce relative names that scripts mis-handle, so normalize paths when needed.

Summary

  • Decide first whether you need working tree, index, or ref-to-ref comparison.
  • Use git diff --name-status and git diff --cached --name-status for precise state views.
  • Use git status --porcelain to include untracked files safely.
  • Filter with --diff-filter when policies depend on change type.
  • Prefer merge-base or explicit ref ranges for branch and release reporting.
  • Keep parsing rules deterministic in scripts to avoid CI surprises.

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.