#!/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, gt-st if [ "$GIT_TRACK_REPOS" ]; then export REPOS="$GIT_TRACK_REPOS" else export REPOS="$HOME/sync/share/git-track.txt" fi # 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}')" # TODO: check if remote_url is not empty 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) list_repos | if [ "$parallel" ]; then parallel gt-cmd "{}" "$OPTARG" else xargs -I{} gt-cmd "{}" "$OPTARG" fi ;; s) list_repos | xargs -I{} gt-st {} ;; l) list_repos ;; e) $EDITOR "$REPOS" ;; f) REPOS="$OPTARG" ;; u) >&2 printf 'pull:\n' if [ "$parallel" ]; then list_repos | parallel gt-cmd {} pull else list_repos | xargs -I{} gt-cmd {} pull fi >&2 printf 'push:\n' list_repos | xargs -I{} gt-st {} | awk -F: '/↑/ {print $1}' | sed "s@^~@$HOME@" | if [ "$parallel" ]; then parallel gt-cmd {} push else xargs -I{} gt-cmd {} push fi ;; h) help ;; :) printf >&2 -- '-%s requires argument\n' "$OPTARG" exit 1 ;; ?) printf >&2 -- 'Invalid option: -%s\n' "$OPTARG" exit 1 ;; esac done