Command line and power tools
A working developer machine has repos everywhere. Finding the one with uncommitted work before wiping a folder is worth a command.
find ~ -type d -name .git -prune 2>/dev/null | sed 's|/.git$||'
-prune stops descent into a repo once found — fast, and it avoids matching nested .git inside dependencies.
With fd:
fd -H -t d '^\.git$' ~ | sed 's|/.git$||'
The genuinely useful query — repos with uncommitted or unpushed work, before you delete or archive anything:
find ~ -type d -name .git -prune 2>/dev/null | while read g; do
d=$(dirname "$g")
s=$(git -C "$d" status --porcelain)
[ -n "$s" ] && echo "DIRTY: $d"
done
Extend it to catch unpushed commits:
git -C "$d" log --branches --not --remotes --oneline | grep -q . && echo "UNPUSHED: $d"
Repos accumulate — .git history plus build output:
find ~ -type d -name .git -prune 2>/dev/null | while read g; do
du -sh "$(dirname "$g")"
done | sort -hr | head -20
find ~ -type d -name .git -prune 2>/dev/null | while read g; do
d=$(dirname "$g")
last=$(git -C "$d" log -1 --format=%cr 2>/dev/null)
echo "$last -- $d"
done
The "2 years ago" entries are archive-or-delete candidates — after the dirty/unpushed check clears them.
.git internals are on Spotlight's exclusion list (thousands of objects that would swamp results), which is correct — but it means locating repos is a Terminal job, or a job for an index that includes them but demotes them below your actual source.
find ~ -type d -name .git -prune then strip the /.git suffix. -prune keeps it fast and avoids nested matches.
Loop the found repos through git status --porcelain; non-empty output means dirty.
Everywhere keeps track of every file on your Mac — including the folders Spotlight hides and drives you have unplugged. Free for a day, then $19 once.
Download for Mac