GitTracking & Untracking Files

Tracking & Untracking Files

Git makes a clear distinction between files it knows about and files that just happen to be in the working directory. A file Git knows about is called tracked; everything else is untracked. The distinction shapes what git status, git diff, and git add . actually do.

The four states a file can be in
  • Untracked — present in the working directory, never staged or committed. Git does not watch it at all.

  • Tracked, unmodified — committed at some point, identical to the last committed version.

  • Tracked, modified — committed at some point, but you have changed it since.

  • Tracked, staged — modified version has been added to the staging area, ready for the next commit.

How a file becomes tracked

git add is the gateway

Bash
touch new-file.txt
git status
# Untracked files:
#   new-file.txt

git add new-file.txt
git status
# Changes to be committed:
#   new file:   new-file.txt

git commit -m "Add new-file.txt"
# Now the file is tracked and unmodified

Tracking begins with git add. The first commit that includes a file makes it permanently tracked until you explicitly remove it.

How a file becomes untracked again

Three ways to stop tracking

Bash
# 1. Remove from disk AND stop tracking
git rm file.txt
git commit -m "Remove file.txt"

# 2. Keep the file on disk, but stop tracking it
git rm --cached file.txt
echo "file.txt" >> .gitignore   # so it doesn't come back next 'git add'
git commit -m "Stop tracking file.txt"

# 3. Reset to a state where the file was never added (before commit only)
git restore --staged file.txt   # unstage
# the file is now untracked again
Listing tracked vs untracked files

Useful inventories

Bash
# Every tracked file in the repo
git ls-files

# Tracked files matching a pattern
git ls-files "*.js"

# Untracked files (anything not in index, not ignored)
git ls-files --others --exclude-standard

# Files ignored by .gitignore
git ls-files --others --ignored --exclude-standard

# Status overview (all states at once)
git status
Why the distinction matters
  • git diff shows changes only in tracked files. Untracked content is invisible.

  • git add . stages new untracked files as well as modifications.

  • git stash (without -u) only stashes changes to tracked files. Use git stash -u to include untracked.

  • git clean deletes untracked files. It cannot touch tracked content — making it relatively safe.

git clean — sweep up untracked files

Remove every untracked file

Bash
# DRY RUN — see what would be deleted
git clean -n

# DELETE every untracked file (NOT ignored ones)
git clean -f

# DELETE untracked files AND folders
git clean -fd

# DELETE untracked AND ignored files (be careful!)
git clean -fdx

# Interactive mode
git clean -i
git clean is destructive
Files removed by `git clean` are NOT recoverable through Git — they were never tracked. Always run with `-n` first to preview.
Special case: re-adding a previously ignored file

Force-add an ignored file

Bash
# Say .env is in .gitignore but you really want to commit a sample
git add --force .env.example
# Without --force, Git refuses to stage an ignored file
Files Git auto-ignores
  • Anything matching the repo’s .gitignore.

  • Anything matching a global ~/.config/git/ignore (or whatever is configured).

  • Anything matching .git/info/exclude (private to this clone).

  • The .git/ directory itself.

Refreshing the index after .gitignore changes

Adding a pattern to .gitignore does NOT untrack files that are already tracked. To stop tracking files that are now matching .gitignore:

Bash
# Remove all tracked files from the index
git rm -r --cached .

# Re-add only the files that aren't ignored
git add .

git commit -m "Apply .gitignore to existing tracked files"
Tip
Run `git status` after any file operation. The output tells you in seconds whether each file is tracked, modified, staged, or untracked. It is the single best feedback loop for learning Git’s tracking model.