git status
Learn how the git status command works, read its long and short output, use --short, --branch and --porcelain, and see what each state means.

The git status command answers a single, constant question while you work: what has changed since my last commit, and what is ready to be committed? It is the command you run more than any other — before staging, before committing, and any time you lose track of where a file stands. This page explains the three states a file can be in, how to read both the long and short output, and the options that make status fit into scripts.
What git status shows
git status displays the state of two things: the working directory (the files on disk you are editing) and the staging area, also called the index (the snapshot you are preparing for the next commit). It tells you which files are:
- Staged — changes added with git add and ready for the next commit.
- Unstaged (modified) — tracked files you have changed but not yet added.
- Untracked — new files Git has never seen and is not following.
What git status does not show is committed history. It says nothing about previous commits, branches you merged, or who changed what — for that, use git log. Nor does it show the content of your changes; to see the exact lines added and removed, use git diff. In short, status summarizes the effect of git add and git commit on your current files.
Basic usage
The command takes no arguments in its most common form:
git statusIn a clean repository with nothing to do, Git tells you so:
On branch master
nothing to commit, working tree cleanReading the long output
The default output (also reachable with --long) is the verbose, human-readable format. Walk a file through its life cycle to see each section appear.
A brand-new file Git has never seen is untracked:
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
w3docs.txt
nothing added to commit but untracked files present (use "git add" to track)After git add w3docs.txt, the same file moves under Changes to be committed — it is now staged:
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: w3docs.txtOnce you git commit, the working tree is clean again. Now edit w3docs.txt and create a second file new.txt. A tracked file that you change appears under Changes not staged for commit, while the brand-new file stays under Untracked files:
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: w3docs.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
new.txt
no changes added to commit (use "git add" and/or "git commit -a")Notice that the hints in parentheses are real, runnable suggestions: Git tells you how to unstage, discard, or add at every step.
The short format
Once you know what the sections mean, the long format becomes noisy. The -s (or --short) flag condenses everything to one line per file:
git status -sFor the state above (one modified tracked file, one new untracked file) it prints:
M w3docs.txt
?? new.txtEach entry has a two-column status code. The left column is the staging area (the index) and the right column is the working tree:
| Code | Meaning |
|---|---|
?? | Untracked file. |
A | Added to the staging area (new file staged). |
M | Modified. Left = change is staged; right = change is unstaged. |
D | Deleted. |
R | Renamed. |
A leading space means "no change in that column." So M means modified but not staged, M means the modification is staged, and MM means a staged change plus further unstaged edits to the same file.
Add -b to also print the current branch and its tracking information:
git status -sb## master
M w3docs.txt
?? new.txtOutput for scripts: --porcelain
If you want to read git status from a script, do not parse the short or long format — both can change between Git versions and are affected by the user's configuration. Use --porcelain instead. It guarantees a stable, machine-readable format:
git status --porcelain M w3docs.txt
?? new.txtThe columns are the same two-character codes as the short format, but the format is contractually stable, making it safe for hooks, CI checks, and shell prompts. Pair it with -z to terminate each entry with a NUL byte instead of a newline, which keeps filenames containing spaces or newlines unambiguous.
Showing ignored files
By default git status hides files matched by your .gitignore rules — build artifacts and binaries such as .pyc, .obj, .exe, or log files would otherwise drown out the real changes. To confirm that a file is being ignored (rather than simply forgotten), add --ignored:
git status --ignoredWith a .gitignore containing *.log and a debug.log on disk, an extra section appears:
Ignored files:
(use "git add -f <file>..." to include in what will be committed)
debug.logThis is the quickest way to debug an ignore rule that is matching more — or less — than you expected.
Common options
| Option | Description |
|---|---|
-s, --short | Output in the short, one-line-per-file format. |
-b, --branch | Show the branch and tracking information (works with the short format). |
--porcelain | Output in a stable, easy-to-parse format for scripts; ignores user configuration. |
--long | Output in the long format (the default). |
-u[<mode>], --untracked-files[=<mode>] | Control untracked files: no shows none, normal shows files and directories, all also lists files inside untracked directories. |
--ignored | Also show files ignored by .gitignore. |
--ignore-submodules[=<when>] | Ignore submodule changes. <when> can be none, untracked, dirty, or all. |
-z | Terminate entries with a NUL byte (implies --porcelain if no format is given). |
--column[=<options>], --no-column | Display untracked files in columns. |
Why check status often
It is good practice to run git status before every git add and git commit. A quick check catches the common mistakes: committing a file you forgot to stage, accidentally staging a debug file, or committing on the wrong branch. Because status only reads the repository and never changes anything, running it is always safe.
Once you have read the status, the natural next steps are to inspect the exact changes with git diff, undo a staging mistake with git reset, or, if you have not started yet, create the repository with git init.