κατάσταση git 2.0

Όποιος είναι πρώτος το πρωί git status Όποιος πληκτρολογεί και μετά πίνει καφέ θα λατρέψει αυτόν τον μικρό βοηθό. Ειδικά όταν αναπτύσσονται πολλά διαδικτυακά έργα παράλληλα, μια συνοπτική επισκόπηση είναι ανεκτίμητη: Πού είναι καθαρό το δέντρο εργασίας, πού υπάρχουν μη συγχωνευμένες αλλαγές και πού εκκρεμεί μια εντολή έλξης/ώθησης; Ένα μικρό εργαλείο κελύφους είναι το μόνο που χρειάζεστε - αρκεί να χειρίζεται κενά/Unicode σε διαδρομές με αξιοπιστία και να μην πνίγεται από κολλημένα τηλεχειριστήρια.


#!/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

Το σενάριο χρειάζεται ακόμα να... chmod +x ~/path/to/script.sh να το κάνει εκτελέσιμο και μπορεί να δημιουργήσει ένα ψευδώνυμο για να αποθηκεύσει πολύτιμη πληκτρολόγηση: Εδώ προσθέτετε στο δικό του ~/.bashrc / ~/.zshrc / ~/.bash_profile η είσοδος alias gscan='bash /path/to/script.sh' επιπλέον. Από τότε και στο εξής, ένα απλό gscan στον επιθυμητό ριζικό κατάλογο.

Ένας λόγος για τον οποίο η δεύτερη εκτέλεση είναι αισθητά ταχύτερη: Κατά την πρώτη εκτέλεση, το σύστημα αρχείων πρέπει να σαρώσει τα πάντα. Στη συνέχεια, τα μεταδεδομένα και πολλά άλλα πράγματα έχουν ήδη υποβληθεί σε επεξεργασία. .git-Οι δομές έχουν προσγειωθεί στην προσωρινή μνήμη σελίδων του πυρήνα του λειτουργικού συστήματος και οι αναφορές και τα γραφήματα υποβολής έχουν ήδη ζεσταθεί. Το επόμενο βήμα... fetch Πλέον, μεταδίδει κυρίως μόνο μικρά δέλτα. Χωρίς πίνακα ελέγχου, χωρίς επιβάρυνση – ένα γρήγορο στιγμιότυπο κατάστασης απευθείας στο τερματικό.

Πίσω