Skip to main content
This guide covers common issues you might encounter when using Dirty and how to resolve them.

Common errors

”cannot access” errors

This error occurs when Dirty cannot access the specified path:
$ dirty /nonexistent
dirty: cannot access '/nonexistent'
Non-existent path
# Check if path exists
ls /path/to/directory

# Use an existing path
dirty ~/code
Permission denied
# Check permissions
ls -la /path/to/directory

# Fix permissions (if appropriate)
chmod +r /path/to/directory

# Or run as user with access
sudo dirty /root/projects
Broken symbolic link
# Check if it's a broken symlink
file /path/to/directory

# Use the actual target path instead
readlink -f /path/to/symlink
dirty $(readlink -f /path/to/symlink)
Relative path issues
# Dirty converts paths with canonicalize() which requires the path to exist
# Use absolute paths or ensure relative paths are correct
pwd  # Check current directory
dirty ./code  # Ensure ./code exists relative to pwd

”No git repos found”

This error means Dirty scanned the directory but didn’t find any .git folders:
$ dirty ~/empty-dir
No git repos found in /home/user/empty-dir
Increase search depthThe default depth is 3. Your repositories might be nested deeper:
# Try deeper scans
dirty -L 5 ~/code
dirty -L 10 ~/code
Check if repositories exist
# Manual verification
find ~/code -name ".git" -type d

# Check first few levels
ls -la ~/code/*/      # depth 1
ls -la ~/code/*/*/    # depth 2
Verify directory structureDirty looks for .git directories, not .git files (which are used by submodules and worktrees):
# This is a repository
project/.git/         # ✓ Found by Dirty

# This is a submodule/worktree reference
submodule/.git        # ✗ Not found by Dirty
Scan the correct directory
# Wrong: scanning home directory with default depth
dirty ~

# Right: scanning code directory specifically
dirty ~/code

”No matching repos found”

This error means Dirty found repositories, but none matched your filters:
$ dirty --dirty ~/code
No matching repos found
You used —dirty but all repos are clean
# No dirty repos found
dirty --dirty ~/code  # Error

# Remove filter to see all repos
dirty ~/code  # Shows all repos
You used —local but all repos have remotes
# No local-only repos found
dirty --local ~/code  # Error

# Check without filter
dirty ~/code  # Shows all repos
Combined filters are too restrictive
# Looking for repos that are both dirty AND local-only
dirty --dirty --local ~/code  # Might find none

# Try filters separately
dirty --dirty ~/code
dirty --local ~/code
This is actually good newsIf dirty --dirty ~/code returns “No matching repos found”, it means all your repositories are clean!
# Verify all repos are clean
if ! dirty --dirty ~/code > /dev/null 2>&1; then
    echo "All repos are clean!"
fi
Dirty skips symbolic links to avoid infinite loops and duplicate scanning:
// From main.rs:64
if path.is_dir() && !path.is_symlink() {
    collect_repos(&path, max_depth, depth + 1, repos);
}

Nested git repositories

Dirty stops at the first .git directory and doesn’t scan subdirectories within repositories:
// From main.rs:55-58
if dir.join(".git").exists() {
    repos.push(dir.to_path_buf());
    return;  // Stop recursing into subdirectories
}
Why Dirty stops at .git directories
  • Performance: Avoids traversing large repository file trees
  • Correctness: Nested .git folders inside a repo are usually submodules or invalid
  • Predictability: One repository = one result
What gets detected
projects/
├── app/
│   ├── .git/           # ✓ Detected
│   └── vendor/
│       └── lib/
│           └── .git/   # ✗ Skipped (inside app repository)
└── tools/
    └── .git/           # ✓ Detected
Intentionally nested repositoriesIf you have repositories nested inside other repositories (not as submodules), you’ll need to scan them separately:
# Only finds outer repo
dirty ~/projects

# Find inner repo directly
dirty ~/projects/app/vendor/lib
Finding all .git directories manuallyTo find all .git directories regardless of nesting:
# This finds ALL .git directories, even nested ones
find ~/code -name ".git" -type d

# Dirty only finds top-level repos
dirty --raw ~/code

SIGPIPE handling

Dirty handles SIGPIPE signals to work correctly in Unix pipelines:
// From main.rs:165
unsafe { libc::signal(libc::SIGPIPE, libc::SIG_DFL) };
The problemWhen piping output to commands like head, the receiving command might close the pipe before Dirty finishes writing:
# head closes pipe after reading first line
dirty --raw ~/code | head -n 1

# Without SIGPIPE handling, Dirty would panic
# With SIGPIPE handling, Dirty exits gracefully
Default Rust behaviorBy default, Rust panics on SIGPIPE, which creates ugly error messages:
# Without SIGPIPE handling:
$ dirty --raw ~/code | head -n 1
app/dashboard
thread 'main' panicked at 'failed printing to stdout: Broken pipe (os error 32)'

# With SIGPIPE handling:
$ dirty --raw ~/code | head -n 1
app/dashboard
When this happensSIGPIPE occurs in these scenarios:
# Piping to head/tail
dirty --raw ~/code | head -n 5

# Piping to grep (if grep exits early)
dirty --raw ~/code | grep -m 1 "app"

# Piping to any command that closes the pipe early
dirty --raw ~/code | while read repo; do echo "$repo"; break; done
You don’t need to worry about thisThis is handled automatically by Dirty. It just works correctly in pipelines.

Frequently asked questions

The --include-unpushed flag requires resolving the upstream tracking branch for each repository and computing graph distance, which involves:
  1. Finding the current branch
  2. Resolving its upstream tracking branch
  3. Computing commits ahead/behind
  4. Handling cases like detached HEAD, no upstream, etc.
This is significantly slower than just checking if files have changed. Only use this flag when you specifically need unpushed commit information.
# Fast: basic dirty check
dirty ~/code

# Slow: includes upstream comparison
dirty --include-unpushed ~/code
Dirty doesn’t have a built-in exclude mechanism, but you can use shell filtering:
# Exclude node_modules directories
dirty --raw ~/code | grep -v "node_modules"

# Exclude multiple patterns
dirty --raw ~/code | grep -vE "(node_modules|target|build)"

# In a script with filtering
dirty --raw ~/code | while read repo; do
    if [[ "$repo" != *"node_modules"* ]]; then
        echo "$repo"
    fi
done
Point Dirty directly at the repository:
# Scan a single repo (depth 0 is fine)
dirty -L 0 ~/code/my-app

# Or use git status directly
git -C ~/code/my-app status
Dirty is designed for scanning multiple repositories. For single repositories, standard git commands are more appropriate.
Git worktrees use a .git file (not directory) that points to the actual git directory:
# Main repository
main/.git/              # ✓ Detected by Dirty

# Worktree (has .git file, not directory)
worktree/.git           # ✗ Not detected by Dirty
Dirty only detects directories with a .git/ folder. Worktrees and submodules (which use .git files) are not detected as separate repositories.To scan worktrees, scan the main repository instead:
# Scan main repo (dirty status includes worktrees)
dirty ~/code/main
No. Dirty looks for .git directories inside working trees. Bare repositories (which are the git directory itself) are not detected.
# Regular repo: has .git/ subdirectory
app/
├── .git/               # ✓ Detected
└── src/

# Bare repo: IS the git directory
app.git/
├── HEAD                # ✗ Not detected
├── objects/
└── refs/
If you need to check bare repositories, use git commands directly:
git --git-dir=/path/to/bare.git status
Yes! Use the --raw flag and check exit codes:
#!/bin/bash
set -e  # Exit on error

if dirty --dirty --raw ~/code > /tmp/dirty-repos.txt 2>&1; then
    # Found dirty repos
    while read repo; do
        echo "Processing $repo"
    done < /tmp/dirty-repos.txt
else
    # No dirty repos (or error)
    echo "No dirty repos found"
fi
See the scripting guide for more examples.

Still having issues?

If you encounter a bug or unexpected behavior:
  1. Check your Dirty version: Ensure you have the latest version
    dirty --version
    cargo install --git https://github.com/iamkaf/dirty  # Update
    
  2. Test with a simple case: Try scanning a directory you know has repositories
    dirty -L 1 ~/code
    
  3. Report the issue: Open an issue on GitHub with:
    • Dirty version
    • Command you ran
    • Expected vs actual behavior
    • Directory structure (if relevant)
Dirty is open source! You can view the source code and report issues at github.com/iamkaf/dirty.

Build docs developers (and LLMs) love