Siapapun yang pertama di pagi hari git status Siapa pun yang mengetik lalu minum kopi pasti akan menyukai alat bantu kecil ini. Terutama saat mengembangkan banyak proyek web secara paralel, ikhtisar ringkas sangat berharga: Di mana pohon kerja yang bersih, di mana ada perubahan yang belum digabungkan, dan di mana tarik/dorong yang tertunda? Anda hanya perlu alat shell kecil – asalkan alat tersebut menangani spasi/Unicode di jalur dengan kuat dan tidak tersendat oleh remote yang macet.
#!/usr/bin/env bash
set -Eeuo pipefail
export LC_ALL=C
# Check if a command exists (no output).
have() { command -v "$1" >/dev/null 2>&1; }
# Ensure we have a `sort` that supports -z (NUL-delimited) input.
SORT_BIN="sort"
if ! "$SORT_BIN" -z </dev/null 2>/dev/null; then
if have gsort && gsort -z </dev/null 2>/dev/null; then
SORT_BIN="gsort"
else
printf 'Error: This script requires "sort -z" (GNU coreutils). Install coreutils (gsort).\n' >&2
exit 1
fi
fi
# Use GNU `timeout` if available; otherwise try `gtimeout` (macOS); otherwise no timeout.
TIMEOUT_BIN="timeout"
if ! have "$TIMEOUT_BIN"; then
if have gtimeout; then
TIMEOUT_BIN="gtimeout"
else
TIMEOUT_BIN=""
fi
fi
# Require git.
if ! have git; then
printf 'Error: "git" not found.\n' >&2
exit 1
fi
# Remove a leading "./" from a path for cleaner output.
trim_dot_slash() {
case "$1" in
./*) printf '%s\n' "${1#./}" ;;
*) printf '%s\n' "$1" ;;
esac
}
# Legend + divider (as requested)
printf '\n🟢: clean\n🟡: behind/ahead\n🔴: modified\n\n----------------------------------\n\n'
# Find all .git directories, NUL-delimited; sort NUL-delimited; iterate safely.
find . -type d -name .git -print0 \
| "$SORT_BIN" -z \
| while IFS= read -r -d '' gitdir; do
repo="${gitdir%/.git}"
display_path="$(trim_dot_slash "$repo")"
# Skip anything that isn't a proper work tree (safety check).
if ! git -C "$repo" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
continue
fi
# Working tree status; include untracked files for a strict "red" signal.
status_out="$(git -C "$repo" status --porcelain=v1 || true)"
# Upstream divergence check (only if an upstream is configured).
ahead=0
behind=0
if git -C "$repo" rev-parse --abbrev-ref --symbolic-full-name '@{u}' >/dev/null 2>&1; then
# Refresh refs; protect with timeout so a hanging remote doesn't stall the loop.
if [ -n "$TIMEOUT_BIN" ]; then
"$TIMEOUT_BIN" 10s git -C "$repo" fetch --all --prune >/dev/null 2>&1 || true
else
git -C "$repo" fetch --all --prune >/dev/null 2>&1 || true
fi
# Count commits only on our side (ahead) and only on upstream's side (behind).
ahead="$(git -C "$repo" rev-list --count --left-only HEAD...@{u} 2>/dev/null || echo 0)"
behind="$(git -C "$repo" rev-list --count --right-only HEAD...@{u} 2>/dev/null || echo 0)"
fi
# Decide the signal:
# - RED if the working tree isn't clean
# - YELLOW if clean but ahead/behind of upstream
# - GREEN otherwise
if [ -n "$status_out" ]; then
printf '🔴 %s\n' "$display_path"
else
if [ "${ahead:-0}" -gt 0 ] || [ "${behind:-0}" -gt 0 ]; then
printf '🟡 %s\n' "$display_path"
else
printf '🟢 %s\n' "$display_path"
fi
fi
done
Naskahnya masih perlu... chmod +x ~/path/to/script.sh membuatnya dapat dieksekusi dan dapat mengatur alias untuk menyimpan pengetikan yang berharga: Di sini Anda menambahkan ke ~/.bashrc / ~/.zshrc / ~/.bash_profile pintu masuk alias gscan='bash /path/to/script.sh' Selain itu. Sejak saat itu, sebuah gscan di direktori root yang diinginkan.
Salah satu alasan mengapa proses kedua terasa lebih cepat: Selama proses pertama, sistem berkas masih harus memindai semuanya; setelah itu, metadata dan banyak hal lainnya sudah diproses. .git-Struktur telah masuk ke cache halaman kernel OS, dan referensi serta grafik komit telah disiapkan. Langkah selanjutnya... fetch Sekarang, sebagian besar hanya mengirimkan delta kecil. Tanpa dasbor, tanpa overhead – snapshot status cepat langsung di terminal.