Skip to content

status Git Command Guide

The git status command displays the state of the working directory and the staging area, showing which changes have been staged, which haven’t, and which files aren’t being tracked by Git.

Terminal window
git status [<options>] [--] [<pathspec>...]
OptionDescription
-s, --shortGive output in short format
--porcelain[=<version>]Give output in machine-readable format
-v, --verboseShow additional information
--column[=<options>]Display output in columns
--no-columnDon’t display in columns
OptionDescription
-b, --branchShow branch and tracking info
--show-stashShow stash state
--ahead-behindShow ahead/behind counts for branches
-u[<mode>], --untracked-files[=<mode>]Show untracked files
--ignored[=<mode>]Show ignored files
OptionDescription
--ignore-submodules[=<when>]Ignore changes to submodules
--no-renamesDon’t detect renames (faster)
ParameterDescription
<pathspec>Limit status to specific paths
Repository State Areas:
├── Working Directory: Files on disk
├── Index (Staging Area): Staged changes ready for commit
├── HEAD: Last commit on current branch
├── Untracked Files: New files not in Git
└── Ignored Files: Files excluded by .gitignore
Status Relationships:
Working Directory ── git add ──► Index ── git commit ──► HEAD
│ │ │
│ │ │
└──────────── git checkout ────┴──────── git reset ──────┘
File Status Symbols:
├── ' ' = unmodified
├── M = modified
├── A = added
├── D = deleted
├── R = renamed
├── C = copied
├── U = updated but unmerged
├── ? = untracked
└── ! = ignored
Status Combinations:
├── ' M' = modified in working directory
├── 'M ' = staged modification
├── 'MM' = modified in both working and staged
├── 'A ' = newly staged file
├── ' D' = deleted in working directory
├── 'D ' = staged for deletion
└── '??' = untracked file
Standard Status Output:
├── Branch Information: Current branch and tracking status
├── Staged Changes: Files staged for commit ("Changes to be committed")
├── Unstaged Changes: Modified files not staged ("Changes not staged")
├── Untracked Files: New files not tracked ("Untracked files")
└── Suggestions: Helpful commands for next steps
Terminal window
# Show full status
git status
# Show status with branch info
git status --branch
# Show status for specific paths
git status src/ README.md
# Show status with stash info
git status --show-stash
Terminal window
# Short format (porcelain-like)
git status --short
git status -s
# Short format with branch info
git status --short --branch
# Short format for specific directory
git status --short docs/
Terminal window
# Machine-readable format
git status --porcelain
# Porcelain v2 format
git status --porcelain=v2
# Parse status in scripts
git status --porcelain | while read -r status file; do
case "$status" in
"M ") echo "Modified: $file" ;;
"A ") echo "Added: $file" ;;
"D ") echo "Deleted: $file" ;;
"??") echo "Untracked: $file" ;;
esac
done
Terminal window
# Show all untracked files
git status --untracked-files=all
# Show only untracked files in directories
git status --untracked-files=normal # Default
# Don't show untracked files
git status --untracked-files=no
# Show untracked files recursively
git status --untracked-files
Terminal window
# Show ignored files
git status --ignored
# Show only ignored files
git status --ignored=matching
# Show ignored files recursively
git status --ignored
Terminal window
# Show detailed branch info
git status --branch --ahead-behind
# Show branch with verbose tracking
git status -b -v
# Show branch status in short format
git status --short --branch
Terminal window
# Display in columns
git status --column
# Column options
git status --column=plain # No colors
git status --column=dense # Compact
git status --column=column # Auto-column
git status --column=row # Row-based
git status --column=auto # Auto-detect
Terminal window
# Configure status behavior
git config status.showUntrackedFiles all # Show all untracked
git config status.relativePaths true # Use relative paths
git config status.submoduleSummary true # Show submodule status
# Configure colors
git config color.status.branch green # Branch color
git config color.status.added green # Added files color
git config color.status.changed red # Changed files color
git config color.status.untracked yellow # Untracked files color
# Configure status display
git config status.short true # Always use short format
Terminal window
# Check status frequently
git status # Before commits
git status --short # Quick checks
git status --porcelain # For scripts
# Use status in workflows
before_commit() {
if ! git diff --quiet; then
echo "You have unstaged changes"
git status --short
return 1
fi
}
# Check for clean working tree
is_clean() {
[ -z "$(git status --porcelain)" ]
}
# Monitor repository state
watch_repo() {
while true; do
clear
git status --short --branch
sleep 2
done
}
Terminal window
# Fast status checks
git status --porcelain # Machine readable
git status --short # Minimal output
git status --no-renames # Skip rename detection
# Limit scope for large repos
git status -- <specific-path> # Check specific paths
git status --ignore-submodules # Skip submodules
# Cache status for performance
# Git automatically caches status info
#!/bin/bash
# Pre-commit status validation
pre_commit_check() {
echo "Pre-commit status check"
# Check for unstaged changes
if ! git diff --quiet; then
echo "Warning: Unstaged changes detected"
git status --short
echo "Stage changes with: git add <files>"
fi
# Check for untracked files
if git status --porcelain | grep -q "^??"; then
echo "Warning: Untracked files detected"
git status --short | grep "^??"
echo "Add files with: git add <files>"
fi
# Check for staged changes
if git diff --cached --quiet; then
echo "No staged changes to commit"
return 1
fi
echo "Status check passed"
}
pre_commit_check
Terminal window
# CI/CD status validation
ci_status_check() {
echo "CI/CD status validation"
# Ensure clean working tree
if ! git diff --quiet --cached; then
echo "Error: Staged changes in CI"
git status
exit 1
fi
# Check for uncommitted changes
if ! git diff --quiet; then
echo "Error: Uncommitted changes in CI"
git status --short
exit 1
fi
# Verify branch state
current_branch=$(git rev-parse --abbrev-ref HEAD)
if [ "$current_branch" = "HEAD" ]; then
echo "Error: Detached HEAD state"
exit 1
fi
echo "CI status validation passed"
}
ci_status_check
Terminal window
# Repository status monitoring
monitor_status() {
echo "=== Repository Status Monitor ==="
# Overall status
git status --short --branch
# File counts by status
echo "File counts:"
git status --porcelain | awk '
BEGIN {modified=0; added=0; deleted=0; untracked=0}
/^M/ {modified++}
/^A/ {added++}
/^D/ {deleted++}
/^\?\?/ {untracked++}
END {
print " Modified: " modified
print " Added: " added
print " Deleted: " deleted
print " Untracked: " untracked
}'
# Recent commits
echo "Recent activity:"
git log --oneline -3
echo "Status monitoring complete"
}
monitor_status
Terminal window
# Refresh status cache
git status --porcelain > /dev/null # Refresh cache
# Check file system state
ls -la file.txt # Check file exists
stat file.txt # Check file metadata
# Reset index if corrupted
git reset --mixed HEAD # Reset staging area
git status # Check status again
Terminal window
# Speed up status in large repos
git status --ignore-submodules # Skip submodules
git status --no-renames # Skip rename detection
git status --untracked-files=no # Skip untracked files
# Use git status alternatives
git diff --name-only # Just changed files
git ls-files --modified # Modified tracked files
Terminal window
# Handle encoding problems
export LC_ALL=en_US.UTF-8
git status
# Configure encoding
git config core.quotepath false # Don't quote UTF-8 paths
git config gui.encoding utf-8 # GUI encoding
# Handle special characters
git status --porcelain # Avoid display issues
Terminal window
# Handle submodule status
git status # Show submodule status
git status --ignore-submodules # Ignore submodule changes
git status --ignore-submodules=dirty # Show only dirty submodules
# Update submodules for accurate status
git submodule update --init
git status
Terminal window
# Fix branch tracking issues
git status --branch # Show branch info
git branch -vv # Show tracking branches
# Set upstream branch
git branch --set-upstream-to=origin/main main
# Check remote status
git remote -v # Check remotes
git fetch # Update remote info
Terminal window
# Control untracked file display
git status --untracked-files=all # Show all untracked
git status --untracked-files=normal # Show in directories
git status --untracked-files=no # Hide untracked
# Check .gitignore
cat .gitignore # Check ignore patterns
git check-ignore -v file.txt # Check why file ignored
Terminal window
# Fix color issues
git config color.status true # Enable colors
git config color.ui true # Enable all colors
# Fix column display
git status --no-column # Disable columns
git status --column=plain # Plain column display
# Check terminal capabilities
echo $TERM # Terminal type
tput colors # Color support
#!/bin/bash
# Development workflow with status checks
dev_workflow_status() {
echo "=== Development Workflow Status ==="
# Check current branch
current_branch=$(git rev-parse --abbrev-ref HEAD)
echo "Current branch: $current_branch"
# Show status overview
git status --short --branch
# Check for common issues
issues_found=0
# Uncommitted changes
if ! git diff --quiet; then
echo "⚠ Uncommitted changes detected"
((issues_found++))
fi
# Unstaged changes
if ! git diff --cached --quiet; then
echo "⚠ Unstaged changes detected"
((issues_found++))
fi
# Untracked files
if git status --porcelain | grep -q "^??"; then
untracked_count=$(git status --porcelain | grep -c "^??")
echo "$untracked_count untracked files"
((issues_found++))
fi
# Ahead/behind remote
if git status --branch --porcelain | grep -q "\[ahead\|behind\]"; then
echo "⚠ Branch is ahead/behind remote"
((issues_found++))
fi
if [ $issues_found -eq 0 ]; then
echo "✓ Repository is clean"
else
echo "Found $issues_found issues to address"
fi
echo "Workflow status check complete"
}
dev_workflow_status
Terminal window
# Prepare commits based on status
prepare_commit() {
echo "Preparing commit based on repository status"
# Get status information
status_info=$(git status --porcelain)
if [ -z "$status_info" ]; then
echo "No changes to commit"
return 0
fi
# Categorize changes
modified_files=$(echo "$status_info" | grep "^M" | wc -l)
added_files=$(echo "$status_info" | grep "^A" | wc -l)
deleted_files=$(echo "$status_info" | grep "^D" | wc -l)
untracked_files=$(echo "$status_info" | grep "^??" | wc -l)
echo "Changes summary:"
echo " Modified: $modified_files"
echo " Added: $added_files"
echo " Deleted: $deleted_files"
echo " Untracked: $untracked_files"
# Interactive staging based on status
echo "Select staging approach:"
echo "1. Stage all changes"
echo "2. Stage modified files only"
echo "3. Interactive staging"
echo "4. Stage by file type"
read -p "Choice (1-4): " choice
case "$choice" in
1) git add --all ;;
2) git add -u ;;
3) git add --patch ;;
4)
read -p "File extension (e.g., .py, .js): " ext
git add "*$ext"
;;
esac
echo "Staging complete. Ready to commit."
}
prepare_commit
Terminal window
# Repository health dashboard using status
repo_health_dashboard() {
echo "=== Repository Health Dashboard ==="
# Basic repository info
echo "Repository: $(basename "$(git rev-parse --show-toplevel)")"
echo "Branch: $(git rev-parse --abbrev-ref HEAD)"
echo "Last commit: $(git log -1 --format='%h %s' --abbrev-commit)"
# Status overview
echo "Status overview:"
git status --short | head -10
# Health metrics
total_files=$(git ls-files | wc -l)
tracked_files=$(git ls-files | wc -l)
staged_changes=$(git diff --cached --name-only | wc -l)
unstaged_changes=$(git diff --name-only | wc -l)
untracked_files=$(git status --porcelain | grep -c "^??")
echo "Health metrics:"
echo " Total tracked files: $tracked_files"
echo " Staged changes: $staged_changes"
echo " Unstaged changes: $unstaged_changes"
echo " Untracked files: $untracked_files"
# Health assessment
health_score=100
if [ $unstaged_changes -gt 0 ]; then
((health_score -= 10))
echo "⚠ Unstaged changes detected"
fi
if [ $untracked_files -gt 10 ]; then
((health_score -= 20))
echo "⚠ Many untracked files"
fi
if ! git diff --quiet --cached; then
((health_score -= 5))
echo "⚠ Staged changes pending commit"
fi
echo "Health score: $health_score/100"
if [ $health_score -ge 90 ]; then
echo "✓ Repository is healthy"
elif [ $health_score -ge 70 ]; then
echo "! Repository needs attention"
else
echo "✗ Repository needs maintenance"
fi
echo "Health dashboard complete"
}
repo_health_dashboard
Terminal window
# Automated status reporting for teams
team_status_report() {
local report_file="team-status-$(date +%Y%m%d).txt"
echo "=== Team Status Report $(date) ===" > "$report_file"
echo "" >> "$report_file"
# Repository status
echo "Repository Status:" >> "$report_file"
git status --short --branch >> "$report_file"
echo "" >> "$report_file"
# Recent activity
echo "Recent Commits:" >> "$report_file"
git log --oneline -5 >> "$report_file"
echo "" >> "$report_file"
# Branch overview
echo "Branch Overview:" >> "$report_file"
git branch -v >> "$report_file"
echo "" >> "$report_file"
# Issues summary
echo "Issues Summary:" >> "$report_file"
issues=0
if ! git diff --quiet; then
echo "- Uncommitted changes present" >> "$report_file"
((issues++))
fi
if git status --porcelain | grep -q "^??"; then
untracked=$(git status --porcelain | grep -c "^??")
echo "- $untracked untracked files" >> "$report_file"
((issues++))
fi
if [ $issues -eq 0 ]; then
echo "- No issues detected" >> "$report_file"
fi
echo "" >> "$report_file"
echo "Report generated: $report_file"
}
team_status_report
# Git hooks using status information
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
# Pre-commit hook with status validation
echo "Pre-commit status validation"
# Check for large files
git status --porcelain | while read -r status file; do
if [ "$status" = "A " ] || [ "$status" = "M " ]; then
size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file")
if [ "$size" -gt 10485760 ]; then # 10MB
echo "Error: Large file detected: $file (${size} bytes)"
echo "Consider using Git LFS for large files"
exit 1
fi
fi
done
# Check for debug statements
if git diff --cached | grep -q "console\.log\|print(\|debugger"; then
echo "Warning: Debug statements detected in staged changes"
echo "Remove debug statements before committing"
exit 1
fi
# Check commit message if provided
if [ -n "$2" ]; then
commit_msg="$2"
if [ ${#commit_msg} -lt 10 ]; then
echo "Error: Commit message too short"
exit 1
fi
fi
echo "Pre-commit validation passed"
EOF
chmod +x .git/hooks/pre-commit
Terminal window
# Monitor status during long operations
monitor_long_operation() {
local operation="$1"
local pid="$2"
echo "Monitoring status during: $operation"
while kill -0 "$pid" 2>/dev/null; do
echo "=== Status at $(date) ==="
git status --short | head -5
echo "Operation still running (PID: $pid)"
sleep 30
done
echo "Operation completed"
echo "Final status:"
git status --short
}
# Usage example
long_running_command &
monitor_long_operation "build process" $!

What’s the difference between git status and git diff?

Section titled “What’s the difference between git status and git diff?”

git status shows which files are staged, modified, or untracked; git diff shows the actual content changes between working directory and staging area.

Use git status —short and look for files with status in the second column, or use git diff —cached to see the actual changes.

What does “Changes not staged for commit” mean?

Section titled “What does “Changes not staged for commit” mean?”

These are modified files that exist in the working directory but haven’t been added to the staging area yet.

How do I hide untracked files from status?

Section titled “How do I hide untracked files from status?”

Use git status —untracked-files=no to hide untracked files, or add them to .gitignore.

What’s the difference between short and porcelain formats?

Section titled “What’s the difference between short and porcelain formats?”

Both are machine-readable, but porcelain is more stable across Git versions and better for scripts.

How do I see status for a specific directory?

Section titled “How do I see status for a specific directory?”

Use git status to limit status output to that directory.

What does “Your branch is ahead/behind” mean?

Section titled “What does “Your branch is ahead/behind” mean?”

Ahead means you have local commits not pushed to remote; behind means remote has commits you haven’t pulled.

Use git status —ignored to show files that are ignored by .gitignore.

Yes, by default it shows submodule status. Use —ignore-submodules to hide submodule information.

What’s the fastest way to check if working tree is clean?

Section titled “What’s the fastest way to check if working tree is clean?”

Use git status —porcelain which returns empty output for clean working tree.

Use git status —column to display status information in columns.

Yes, it can detect renamed files. Use —no-renames to disable rename detection for performance.

Use git status —branch or -b to show current branch and tracking information.

What’s the difference between —ignored and —ignored=matching?

Section titled “What’s the difference between —ignored and —ignored=matching?”

—ignored shows all ignored files; —ignored=matching shows only ignored files that match patterns.

Yes, use git status —show-stash to include information about stashed changes.

Use git status —ahead-behind to show how many commits ahead or behind the tracking branch.

—verbose shows additional information like the commit the branch is tracking.

Yes, you can limit status to specific paths: git status

Use git config color.status false or redirect output to disable colors.

What’s the performance impact of git status?

Section titled “What’s the performance impact of git status?”

Generally fast, but can be slow in large repos with many untracked files. Use —untracked-files=no to speed it up.

Yes, it shows ahead/behind information for tracking branches.

Git automatically manages status cache, but you can force refresh by running git status.

Can git status detect file permission changes?

Section titled “Can git status detect file permission changes?”

Yes, it shows files with changed permissions as modified.

Use —porcelain for machine-readable format, or —short for human-readable compact format.

  1. Repository Monitoring: Checking current state before operations
  2. Workflow Management: Understanding what needs to be staged/committed
  3. Script Integration: Machine-readable output for automation
  4. Code Review Preparation: Ensuring clean state for reviews
  5. Debugging: Identifying unexpected repository state
  6. Team Coordination: Sharing repository status with team members
  7. CI/CD Integration: Validating repository state in pipelines
  8. Development Hygiene: Maintaining clean working directory