Skip to content

Instantly share code, notes, and snippets.

@ardabbour
Created May 11, 2022 12:56
Show Gist options
  • Save ardabbour/1aa41cff87b1e843550f3bddfa44150a to your computer and use it in GitHub Desktop.
Save ardabbour/1aa41cff87b1e843550f3bddfa44150a to your computer and use it in GitHub Desktop.
Executes a given command recursively on every git repository found under a given directory.
#!/usr/bin/env bash
# -*- coding: utf-8 -*-
###
# git-recursive
#
# This script will execute a given command recursively on every git repository
# found under the current directory.
#
# Copyright 2022 Abdul Rahman Dabbour
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
###
BYellow='\033[1;33m'
Color_Off='\033[0m'
usage="$(basename "$0") [-h] [-c COMMAND] [-d DIRECTORY] -- execute a command on every git repo found recursively
where:
-h show this help text
-c command to execute (default: 'git status')
-d directory (default: current directory)"
CMD="git status"
REQUESTED_DIR="$(pwd)"
while getopts hd:c: o; do
case "$o" in
h)
echo "$usage" 1>&2
exit 0
;;
d) REQUESTED_DIR="$OPTARG" ;;
c) CMD="$OPTARG" ;;
[?])
echo "$usage" 1>&2
exit 1
;;
esac
done
shift $((OPTIND-1))
start_dir=$(pwd)
# set the arguments
REQUESTED_DIR=$(realpath "$REQUESTED_DIR")
cd "$REQUESTED_DIR" || exit 1
# get all the .git paths and store them in a temp file
tempfile="tempfile""$(date +%Y%m%d%H%M%S%N)"
find . -path '*/.git/config' -execdir pwd \; >"$tempfile"
echo -e "${BYellow}will execute \"${CMD}\" in every git repo found under ${REQUESTED_DIR} in 3 seconds${Color_Off}"
echo -e "${BYellow}3...${Color_Off}"
sleep 1
echo -e "${BYellow}2...${Color_Off}"
sleep 1
echo -e "${BYellow}1...${Color_Off}"
sleep 1
# go through each .git path
while IFS="" read -r p || [ -n "$p" ]; do
cd "$(dirname "$p")" || exit
echo -e "${BYellow}currently in: $(dirname "$p")${Color_Off}"
$CMD
cd "$REQUESTED_DIR" || exit
done <"$tempfile"
rm "$tempfile"
cd "$start_dir" || exit
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment