git կարգավիճակ 2.0

Ով որ առավոտյան առաջինն է, git status Այս փոքրիկ օգնականը կսիրի յուրաքանչյուր ոք, ով միաժամանակ գրում է, ապա խմում սուրճ։ Հատկապես, երբ զուգահեռաբար մշակվում են բազմաթիվ վեբ նախագծեր, համառոտ ակնարկը անգնահատելի է. որտե՞ղ է աշխատանքային ծառը մաքուր, որտե՞ղ կան չմիավորված փոփոխություններ, և որտե՞ղ է ձգում/մղում գործողությունը սպասման մեջ։ Ձեզ անհրաժեշտ է միայն մի փոքր shell գործիք, եթե այն հուսալիորեն մշակում է բացատները/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 Այժմ այն հիմնականում փոխանցում է միայն փոքր դելտաներ։ Չկա վահանակ, չկա վերադիր ծախսեր՝ կարգավիճակի արագ պատկեր անմիջապես տերմինալում։

Վերադառնալ