Git Status

git status shows you the current state of your working directory and staging area — which files are tracked, which have been modified, which are staged for the next commit, and which Git doesn’t know about at all. It’s the command I run more than any other Git command, usually right before deciding what to do next. This is the sixth post in this site’s Git command guide, following Git Commit.

Basic Usage

Say you’re working on a feature and you’ve edited a file. Running git status on a repo tracking against main looks like this:

$ git status
On branch main
Your branch is up to date with 'origin/main'.

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:   index.html

no changes added to commit (use "git add" and/or "git commit -a")

Git is telling you index.html has been modified but isn’t staged yet — your changes exist in the working directory, but they won’t be part of the next commit until you run git add. Notice the suggested command is git restore, not the old git checkout -- — that’s a Git 2.23+ wording change, covered in more detail in Git Checkout.

After staging that file, the same command looks different:

$ git add index.html
$ git status
On branch main
Your branch is up to date with 'origin/main'.

Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
	modified:   index.html

Short Format: git status -s

The full output is readable but verbose. When I just want a quick scan — especially with several files changed — I use -s (or --short):

$ git status -s
 M  index.html
A  styles.css
?? notes.txt

Each line has two columns. The first character is the staging-area state, the second is the working-tree state. So M with the space second means index.html is modified and already staged; A means styles.css was newly added and staged; ?? means notes.txt isn’t tracked by Git at all yet.

How .gitignore Affects git status

Files matched by patterns in .gitignore are excluded from the “Untracked files” section entirely — git status won’t mention them unless you ask. This is why a build directory like target/ in a Maven project, or node_modules/ in a frontend one, doesn’t clutter the output once it’s listed in .gitignore. If you ever need to double-check what’s being ignored and why, git status --ignored will list them explicitly:

$ git status --ignored
On branch main
Your branch is up to date with 'origin/main'.

Ignored files:
  (use "git add -f <file>..." to track)
	target/
	.env

nothing to commit (working tree clean)

One gotcha worth knowing: if a file was already tracked by Git before you added it to .gitignore, ignoring it won’t make git status stop reporting changes to it. You have to explicitly untrack it first with git rm --cached <file>.

How the Code Works

  • “Changes not staged for commit” — tracked files that were modified in the working directory but not yet git added.
  • “Changes to be committed” — staged changes that will be included in the next git commit.
  • “Untracked files” — files Git has never been told to track, and that aren’t matched by .gitignore.
  • -s/--short compresses each entry to a two-character status code per file, useful for scripting or scanning many changes at once.

Reference: Short-Format Status Codes

CodeMeaning
M Modified, staged
MModified, not staged
A New file, staged
D Deleted, staged
R Renamed, staged
??Untracked
!!Ignored (only shown with --ignored)

FAQs

Does git status change anything in my repository?

No, it’s read-only. It compares your working directory, the staging area, and the last commit, and reports the differences without modifying any of them.

Why does git status show a file as modified when I haven’t touched it?

Usually line-ending conversion (CRLF vs LF) triggered by core.autocrlf, or a tool that touched the file’s timestamp/permissions without changing content. Run git diff <file> to see exactly what Git thinks changed.

What does “Your branch is up to date with ‘origin/main'” mean?

It means your local main and the remote-tracking branch origin/main point at the same commit, based on the last time you fetched. It does not guarantee the remote hasn’t moved since then — run git fetch first if you need a fresh comparison.

See Also: This Site’s Git Command Guide

This post is part of a 13-part Git command guide on this site:

Conclusion

If you only learn one Git habit, make it this: run git status before every add, every commit, and every checkout. It costs nothing and it’s the single best way to avoid committing the wrong files or losing track of what’s staged. Once your changes are organized the way you want, the next step in the workflow is creating or switching branches — covered in Git Branch.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.