#!/bin/sh # Git Trach, track the state of multiple repos from a single file. # dependencies: # - git # - $EDITOR: -e # - parallel: optional, if installed will run the commands on all repos with parallel # - gt-[cmd,st,sync] repos=$HOME/sync/share/git-track.txt # prevent file not found errors touch "$repos" || exit 1 which parallel >/dev/null 2>&1 && parallel=1 help() { cat >&2 </dev/null | while read -r line; do # \r\033[0K : clear current line printf >&2 '\r\033[0K%s' "$line" done } # no options if [ -z "$1" ]; then help exit 1 fi [ "$(wc -l <"$repos")" -gt 0 ] || exit 0 while getopts ":a:c:f:lsheu" opt; do case "$opt" in a) if ! cd "$OPTARG" 2>/dev/null; then >&2 printf 'Not a directory.\n' exit 1 fi repo="$(git rev-parse --show-toplevel)" remote_url="$(git remote show -n origin | awk '/^ Fetch/ {print $NF}')" if grep "^$repo " "$repos" >/dev/null 2>&1; then printf >&2 'added already.\n' exit 3 fi printf '%s %s\n' "$repo" "$remote_url" >>"$repos" printf >&2 'added.\n' ;; c) cut -f 1 -d ' ' "$repos" | if [ "$parallel" ]; then parallel gt-cmd "{}" "$OPTARG" else xargs -I{} gt-cmd "{}" "$OPTARG" fi ;; s) cut -f 1 -d ' ' "$repos" | xargs -I{} gt-st {} ;; l) cut -f 1 -d ' ' "$repos" ;; e) $EDITOR "$repos" ;; f) repos="$OPTARG" ;; u) if [ "$parallel" ]; then parallel --colsep ' ' gt-sync {1} {2} <"$repos" else IFS=' ' while read -r repo remote_url; do gt-sync "$repo" "$remote_url" done <"$repos" fi | awk -F ':' '/x$/ {print $1}' | if [ "$parallel" ]; then parallel gt-cmd {} pull else xargs -I{} gt-cmd {} pull fi ;; h) help ;; :) printf >&2 -- '-%s requires argument\n' "$OPTARG" exit 1 ;; ?) printf >&2 -- 'Invalid option: -%s\n' "$OPTARG" exit 1 ;; esac done # eval "herbe $(status | sed 's/"/\"/g;s/.*/"&"/' | tr '\n' ' ')"