Review before committing
Before running git commit, check which files are staged and which edits you still need to git add.
Git · Command
git status reports the state of your working tree. It lists what is staged for the next commit, what has changed but is not staged, and which files Git is not tracking.
Last updated
Git makes three comparisons. It compares HEAD with the index, which gives the changes that a plain commit would record. It compares the index with the working tree, which gives edits you have not staged yet. It also scans for files that are neither tracked nor ignored. The default long output is meant for people and includes hints about what to do next. The short format (-s) shows each path with a two-letter XY code. The --porcelain format looks like the short format, but it is meant for scripts and stays stable. By default, status also refreshes the cached stat information in the index and writes it back, so later commands don't have to repeat that work.
git status [<options>] [--] [<pathspec>…]| Name | Type | Description |
|---|---|---|
-s, --short | flag | Prints the compact XY-code format. |
-b, --branch | flag | Adds the branch name and upstream tracking info to short output. |
--show-stash | flag | Shows how many stash entries exist. |
--porcelain[=<version>] | flag (v1 | v2) | Machine-parseable output that stays stable. Defaults to v1. |
--long | flag | Human-readable long format. This is the default. |
-v, --verbose | flag | Also shows the staged diff. Give it twice to also show the unstaged diff. |
-u[<mode>], --untracked-files[=<mode>] | no | normal | all | Controls how untracked files are listed. With no mode given, it means all. |
--ignore-submodules[=<when>] | none | untracked | dirty | all | Controls which submodule changes are ignored. Defaults to all. |
--ignored[=<mode>] | traditional | no | matching | Also lists ignored files. |
-z | flag | Ends entries with NUL instead of LF. Implies --porcelain=v1 unless another format is given. |
--column[=<options>], --no-column | flag | Shows untracked files in columns. |
--ahead-behind, --no-ahead-behind | flag | Turns detailed ahead/behind counts against the upstream on or off. On by default. |
#!/usr/bin/env bash
set -euo pipefail
# Human-friendly overview with branch info
git status -sb
# Stable, script-safe check (no lock contention)
changes=$(git --no-optional-locks status --porcelain=v1)
if [ -n "$changes" ]; then
echo "Working tree is not clean:" >&2
echo "$changes" >&2
exit 1
fi
echo "Clean - safe to release"The script prints a short status with branch info, then uses lock-free porcelain output to exit with an error if anything is staged, modified or untracked.
Before running git commit, check which files are staged and which edits you still need to git add.
After a build or code generation step, have the pipeline run git status --porcelain and fail if any files changed unexpectedly.
Show the branch, ahead/behind counts and dirty state using --porcelain=v2 --branch, and run it with --no-optional-locks so it doesn't block other Git processes.
Find the unmerged paths (UU, AA and similar codes) that still need resolving before you finish a merge, rebase or cherry-pick.
First, paths that differ between HEAD and the index; these are what a commit would record. Second, paths that differ between the index and the working tree. Third, untracked files that are not ignored. You would have to git add the second and third groups before committing them.
Follow-up: How do you see the actual content changes and not just file names? Pass -v to include the staged diff, like git diff --cached, and pass -v -v to add the unstaged diff too.
The left character X is the index, and the right character Y is the working tree. 'M ' means the change is staged and the working tree matches the index. ' M' means the file was modified but not staged. '??' means the file is untracked.
Follow-up: What does 'UU' mean? It is an unmerged path where both sides of the merge modified the file, so the conflict still needs to be resolved.
The long format is meant for people and may change at any time. Porcelain output is guaranteed to stay backward-compatible and ignores user settings such as color.status and status.relativePaths. For filenames with unusual characters, add -z so entries end with NUL and nothing is quoted.
Follow-up: When would you choose v2 over v1? Choose v2 when you need branch headers (oid, head, upstream, ahead/behind), file modes and object names, or rename scores with the original path.
git addgit diffgit commitgit restoregit stashgit update-indexgitignoregit-config