diff options
author | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-20 12:01:39 +0200 |
---|---|---|
committer | Raymaekers Luca <raymaekers.luca@gmail.com> | 2024-06-20 12:01:39 +0200 |
commit | 947f7df73f16981f170265a64a964142fc617023 (patch) | |
tree | 75c7f8560539303e4a5c1f93241a1e8912bad4cc /bin/common/gt | |
parent | ff6c38d3364165a7bae431888a87aab1e53a80b9 (diff) |
checkpoint
Diffstat (limited to 'bin/common/gt')
-rwxr-xr-x | bin/common/gt | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/bin/common/gt b/bin/common/gt new file mode 100755 index 0000000..bdbd00f --- /dev/null +++ b/bin/common/gt @@ -0,0 +1,111 @@ +#!/bin/sh + +# Git Trach, track the state of multiple repos from a single file. + +# dependencies: +# - git +# - $EDITOR: -e +# - herbe (optional): -s + +repos="${XDG_DATA_HOME:-$HOME}"/git-track.txt +touch "$repos" + +help() { + >&2 cat <<EOF +usage: gt [OPTION] +-a PATH add repo +-s update and show status of each repo +-c COMMAND run 'git COMMAND' in each repo +-h show this help +-l list repos +-e edit repos in $EDITOR +EOF +} + +# fetch repository prettily, outputs nothing if failed +fetch() { + # fetch with one-line printing of progress + git fetch --progress 2>/dev/null | while read -r line + # \r\033[0K : clear current line + do >&2 printf '\r\033[0K%s' "$line" + done +} + +# Print repositories prettily +# This function function prints animations (eg. clearing the line) +# to stderr and the final status line is outputted to stdout. +status() { + while read -r repo + do + repo_pretty="$(printf '%s' "$repo" | sed "s@$HOME@~@" )" + + # absolute path + cd "$repo" + + # replace line with status + >&2 printf '\r\033[0K' + + status="$(git status --porcelain 2> /dev/null | awk '{print $1}' | uniq | tr -d '\n')" + remote="$(git branch -v 2>/dev/null | sed 's/ahead/↑/;s/behind/↓/;s/[^↓↑]*//g')" + + printf '%s %s %s\n' "$repo_pretty" "$status" "$remote" + done < "$repos" +} + +# run git command in each repo +# $1: command +repos_cmd() { + while read -r repo + do + repo_pretty="$(printf '%s' "$repo" | sed "s@$HOME@~@" )" + printf ''\''%s'\'' in %s' "$1" "$repo_pretty" + ( + cd "$repo" + git "$1" > /dev/null 2>&1 + [ $? -gt 0 ] && s="x" || s="o" + printf '\r\033[0K%s: %s\n' "$repo_pretty" "$s" + ) + done < "$repos" +} + +# no options +if [ -z "$1" ] +then + help + exit 1 +fi + +while getopts ":a:c:f:lshe" opt +do + case "$opt" in + a) + cd "$OPTARG" || exit 1 + r="$(git rev-parse --show-toplevel)" + [ "$r" ] || exit 2 + + if grep "$r" "$repos" > /dev/null 2>&1 + then + >&2 printf 'added already.\n' + exit 2 + fi + + printf '%s\n' "$r" >> "$repos" + + >&2 printf 'added.\n' ;; + c) repos_cmd "$OPTARG" ;; + s) status=1 ;; + l) cat "$repos" ;; + e) $EDITOR "$repos" ;; + f) repos="$OPTARG" ;; + T) help ;; + :) >&2 printf -- '-%s requires argument\n' "$OPTARG"; exit 1 ;; + ?) >&2 printf -- 'Invalid option: -%s\n' "$OPTARG"; exit 1 ;; + esac +done + +if [ "$status" ] +then + status + which herbe > /dev/null 2>&1 && + eval "herbe $(status | sed 's/"/\"/g;s/.*/"&"/' | tr '\n' ' ')" & +fi |