Skip to content

Instantly share code, notes, and snippets.

@mekanics
Created April 9, 2026 10:53
Show Gist options
  • Select an option

  • Save mekanics/27d25f81fbfdc60166372ca71d99823e to your computer and use it in GitHub Desktop.

Select an option

Save mekanics/27d25f81fbfdc60166372ca71d99823e to your computer and use it in GitHub Desktop.
#!/usr/bin/env bash
# git-diagnostic.sh
# Based on: https://piechowski.io/post/git-commands-before-reading-code/
# Runs five git diagnostics before reading a codebase.
set -euo pipefail
# ── helpers ────────────────────────────────────────────────────────────────────
RED=’\033[0;31m’
YELLOW=\033[1;33m’
CYAN=\033[1;36m’
BOLD=\033[1m’
RESET=\033[0m’
header() {
echo
echo -e “${CYAN}${BOLD}══════════════════════════════════════════════════════════${RESET}
echo -e “${CYAN}${BOLD} $1${RESET}
echo -e “${CYAN}${BOLD}══════════════════════════════════════════════════════════${RESET}
}
warn() { echo -e “${YELLOW}$1${RESET}; }
info() { echo -e “ $1; }
# ── guard ──────────────────────────────────────────────────────────────────────
if ! git rev-parse –git-dir &>/dev/null; then
echo -e “${RED}Not inside a git repository.${RESET}
exit 1
fi
REPO_ROOT=$(git rev-parse –show-toplevel)
echo -e\n${BOLD}Repository:${RESET} $REPO_ROOT
# ── 1. What changes the most ───────────────────────────────────────────────────
header “1 / 5 · What Changes the Most (top 20 files, last year)”
git log –format=format: –name-only –since=“1 year ago”
| grep -v ‘^$’
| sort | uniq -c | sort -nr | head -20
| awk ‘{printf “ %5d %s\n”, $1, $2}’
info “”
info “High-churn files that nobody wants to own = codebase drag.”
info “Cross-reference with section 3 (bug clusters) for highest-risk files.”
# ── 2. Who built this ──────────────────────────────────────────────────────────
header “2 / 5 · Who Built This (all time vs. last 6 months)”
echo -e\n ${BOLD}All time:${RESET}
git shortlog -sn –no-merges
| head -20
| awk ‘{printf “ %5d %s\n”, $1, substr($0, index($0,$2))}’
TOTAL_COMMITS=$(git shortlog -sn –no-merges | awk ‘{sum+=$1} END{print sum}’)
TOP_COMMITS=$(git shortlog -sn –no-merges | head -1 | awk ‘{print $1}’)
if [[ $TOTAL_COMMITS -gt 0 ]]; then
TOP_PCT=$(( TOP_COMMITS * 100 / TOTAL_COMMITS ))
if [[ $TOP_PCT -ge 60 ]]; then
warn “Top contributor owns ${TOP_PCT}% of commits — high bus factor risk.”
fi
fi
echo -e\n ${BOLD}Last 6 months:${RESET}
RECENT=$(git shortlog -sn –no-merges –since=“6 months ago”)
if [[ -z$RECENT” ]]; then
warn “No commits in the last 6 months.”
else
echo$RECENT
| head -20
| awk ‘{printf “ %5d %s\n”, $1, substr($0, index($0,$2))}’
fi
TOP_ALL=$(git shortlog -sn –no-merges | head -1 | sed ‘s/^[[:space:]]*[0-9]*[[:space:]]*//’)
if [[ -n$RECENT” ]] && ! echo$RECENT| grep -q “$TOP_ALL; then
warn “Top all-time contributor "$TOP_ALL" is absent from the last 6 months.”
fi
info “”
info “Note: squash-merge workflows compress authorship — commits reflect who merged, not who wrote.”
# ── 3. Where do bugs cluster ──────────────────────────────────────────────────
header “3 / 5 · Where Do Bugs Cluster (top 20 files, fix/bug commits)”
BUG_FILES=$(git log -i -E –grep=“fix|bug|broken” –name-only –format=’’
| grep -v ‘^$’
| sort | uniq -c | sort -nr | head -20)
if [[ -z$BUG_FILES” ]]; then
warn “No commits matched fix|bug|broken — team may not use descriptive commit messages.”
else
echo$BUG_FILES
| awk ‘{printf “ %5d %s\n”, $1, $2}’
info “”
info “Files appearing in both this list and section 1 are your highest-risk code.”
fi
# ── 4. Is the project accelerating or dying ───────────────────────────────────
header “4 / 5 · Commit Velocity by Month (full history)”
git log –format=’%ad’ –date=format:’%Y-%m’
| sort | uniq -c
| awk ‘{printf “ %s %5d %s\n”, $2, $1, “·”}’
info “”
info “Steady rhythm = healthy. Halved count in a single month = someone left.”
info “Declining trend over 6-12 months = team losing momentum.”
info “Spikes + quiet months = batch releases instead of continuous shipping.”
# ── 5. How often is the team firefighting ─────────────────────────────────────
header “5 / 5 · Firefighting Frequency (revert/hotfix/emergency, last year)”
CRISIS=$(git log –oneline –since=“1 year ago”
| grep -iE ‘revert|hotfix|emergency|rollback’ || true)
if [[ -z$CRISIS” ]]; then
info “No revert/hotfix/emergency/rollback commits found in the last year.”
info “Either the team is stable, or commit messages aren’t descriptive.”
else
COUNT=$(echo “$CRISIS| wc -l | tr -d ’ ‘)
echo$CRISIS| sed ‘s/^/ /’
echo
if [[ $COUNT -gt 12 ]]; then
warn “${COUNT} crisis commits in the last year (~every few weeks).”
warn “Team likely doesn’t trust its deploy process: check tests, staging, rollback pipeline.”
else
info “${COUNT} crisis commit(s) in the last year — within normal range.”
fi
fi
# ── done ──────────────────────────────────────────────────────────────────────
echo
echo -e${BOLD}Done.${RESET} Cross-reference sections 1 & 3 to find your highest-risk files.”
echo
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment