#!/usr/bin/env sh # POSIX shell implementation of Gitrect # # Operate on a tempfile and generate a listing of: # # prefix-trim-directory,remote=URL,... # # For all directories found in $WORKDIR # if [ ! "$(command -v git)" ]; then echo "git command not found. git must be installed and available in \$PATH to continue" exit 1 fi # Reset all variables that might be set DEFAULT_STATE="$HOME/.local/share/git/repolist" WORKDIR="$HOME/.code" verbose=0 # Variables to be evaluated as shell arithmetic should be initialized to a default or validated beforehand. GITVER="$(git version | cut -d " " -f 3)" usage="$(basename "$0") [-h] [-v -w WORKDIR -f FILE] Set remotes for all git repos and pull new changes where: -w set the (base) working directory (default: ${WORKDIR}) -f set the git list file (default: ${DEFAULT_STATE}) -h show this help text -v increase output verbosity " while :; do case $1 in -h | -\? | --help) # Call a "show_help" function to display a synopsis, then exit. echo "$usage" exit ;; -f) # Takes an option argument, ensuring it has been specified. if [ -n "$2" ]; then DEFAULT_STATE="$2" shift fi ;; -f=?*) DEFAULT_STATE=${1#*=} # Delete everything up to "=" and assign the remainder. ;; -f=) # Handle the case of an empty --file= printf 'ERROR: "-f" requires a non-empty option argument.\n' >&2 exit 1 ;; -w) # Takes an option argument, ensuring it has been specified. if [ -n "$2" ]; then WORKDIR="$2" shift fi ;; -w=?*) WORKDIR=${1#*=} # Delete everything up to "=" and assign the remainder. ;; -w=) # Handle the case of an empty --file= printf 'ERROR: "-w" requires a non-empty option argument.\n' >&2 exit 1 ;; -v) verbose=$((verbose + 1)) # Each -v argument adds 1 to verbosity. ;; --) # End of all options. shift break ;; -?*) printf 'WARN: Unknown option (ignored): %s\n' "$1" >&2 ;; *) # Default case: If no more options then break out of the loop. break ;; esac shift done # No posix-compliant way of getting separator, so leverage OS-specifics FS_SEPARATOR="/" # Don't care about windows, will figure it out another day while read -r line; do dir=$(echo "$line" | cut -d, -f 1) remlist=$(echo "$line" | cut -d, -f 2-) clone=0 #False if [ $verbose -gt 0 ]; then echo "Operating on ${WORKDIR}${FS_SEPARATOR}${dir}" fi if [ ! -d "${WORKDIR}${FS_SEPARATOR}${dir}" ]; then #clone repo clone=$((clone + 1)) # Set true mkdir -p "${WORKDIR}${FS_SEPARATOR}${dir}" fi cd "${WORKDIR}${FS_SEPARATOR}${dir}" || exit if [ $clone -gt 0 ]; then if [ ${GITVER} \> "2.45" ]; then git init --ref-format=reftable else git init fi fi if [ $verbose -gt 1 ]; then echo "Remote url: ${remlist}" fi localRemotes=$(eval "git remote") len_localRemotes=${#localRemotes} echo "${remlist}" | awk -F ',' '{for (i = 1; i <= NF; i++) {printf "%s \n", $i}; printf "\n"}' | while read -r r || [ -n "$r" ]; do remoteName=$(echo "$r" | awk -F'=' '{print $1}') # Just get the remote name # Allow for blank / newlines during processing if [ "${remoteName}" = "" ]; then continue; fi if [ $len_localRemotes -gt 0 ]; then remExistsCheck=$(eval "git config remote.${remoteName}.url") if [ "${remExistsCheck}" = "" ]; then if [ $verbose -gt 0 ]; then echo "Adding remote ${r}" fi echo "$r" | awk -F'=' '{ print $1, $2; }' | xargs -n 2 git remote add else if [ $verbose -gt 0 ]; then echo "Setting remote ${r}" fi echo "$r" | awk -F'=' '{ print $1, $2; }' | xargs -n 2 git remote set-url fi else # Remotes not set locally if [ $verbose -gt 0 ]; then echo "Adding remote ${r}" fi echo "$r" | awk -F'=' '{ print $1, $2; }' | xargs -n 2 git remote add fi done if [ $verbose -gt 1 ]; then echo "Listed remotes for ${dir} are:" git remote -v fi if [ $clone -gt 0 ]; then git fetch --all rev=$(git ls-remote origin | grep HEAD | cut -f 1) if [ $verbose -gt 0 ]; then echo "Rev: ${rev}" fi br=$(git ls-remote origin | grep "${rev}" | grep -v HEAD | cut -f 2 | cut -d / -f 3 | head -n 1) if [ "$verbose" -gt 0 ]; then echo "Branch: ${br}" fi git switch "$br" fi done <"$DEFAULT_STATE" # Re-run confgit if it exists if [ "$(command -v confgit.sh)" ]; then confgit.sh fi # Update all remotes if we have the fetchgit command if [ "$(command -v fetchgit)" ]; then if [ "$verbose" -gt 0 ]; then find "$WORKDIR" -name ".git" -exec fetchgit -v {} \; else find "$WORKDIR" -name ".git" -exec fetchgit {} \; fi fi