A small toolbox of Bash scripts for everyday developer chores: auditing and
cleaning up git clones, watching slow clones, shrinking media for the web,
freeing ports and fixing terminals on remote hosts.
Every script:
- runs on Linux and macOS (GNU and BSD userlands)
- prints usage with
-h / --help
- uses
set -u / pipefail, validates its arguments, and exits non-zero on error
- is non-destructive by default where it could lose data (dry runs, no overwrites)
git clone <this-repo> ~/scripts
echo 'export PATH="$HOME/scripts:$PATH"' >> ~/.bashrc # or ~/.zshrc
| Script |
What it does |
repo-status.sh |
One line per git clone under a directory: branch, ahead/behind, uncommitted changes, last commit age and optional disk size. Sortable. |
find-repo-clones.sh |
Find every clone of a repo by origin URL, or list all repos under a tree. --paths output pipes into the other tools. |
check-branches-status.sh |
Answers "is it safe to delete this clone?": uncommitted work, stashes, worktrees, unpushed commits, gone upstreams and dangling commits. |
prune-merged-branches.sh |
Delete local branches whose every commit already exists on a remote. Dry run unless --apply. |
clonewatch |
Live throughput and phase for git clone / fetch / submodule transfers already running. Read-only. |
| Script |
What it does |
compress-video.sh |
Re-encode a video to web-friendly H.264 (scaled, faststart, audio dropped by default). Never overwrites. Needs ffmpeg. |
convert-images-to-webp.sh |
Convert JPEG/PNG files under a directory to WebP, keeping the original whenever WebP isn't smaller. Needs cwebp. |
| Script |
What it does |
port-kill.sh |
Kill whatever is listening on a TCP port (not clients connected to it). Skips other users' processes. |
fix-ghostty-on-remote.sh |
Install your local terminfo entry on a remote host over SSH, fixing "unknown terminal type". Works for any $TERM, not only Ghostty. |
| Script |
What it does |
scaffold |
Create a new script from the shared template (usage banner, die, option loop). Every script here started from it. |
# What needs attention across all my repos?
repo-status.sh --dirty --sort sync ~/code
# Before deleting old clones: do any of them hold work that exists only locally?
find-repo-clones.sh --paths --root ~/code | xargs check-branches-status.sh --quiet
# Clean up merged branches after a release
prune-merged-branches.sh --fetch ~/code/my-project # look first
prune-merged-branches.sh --fetch --apply ~/code/my-project # then delete
# Shrink a hero video and every image in a site's assets
compress-video.sh --height 720 public/hero.mp4
convert-images-to-webp.sh --dry-run public/images
# Something is squatting on port 3000
port-kill.sh 3000
# Start a new script
scaffold my-tool
Scripts share a convention:
| Code |
Meaning |
0 |
success |
1 |
runtime failure, or the check found a problem |
2 |
usage error |
3 |
refused, e.g. the target already exists |