diff options
-rwxr-xr-x | foreach-git | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/foreach-git b/foreach-git new file mode 100755 index 0000000..9ad529f --- /dev/null +++ b/foreach-git @@ -0,0 +1,64 @@ +#! /usr/bin/env bash + +# Run git command in each directory that looks like a git repository. By +# default only top-level directoris are considered but the depth can be +# adjusted with -d. +# +# -x <dir> +# Exclude <dir>. +# +# -n <num> +# Directory depth to consider. +# +# + +trap "{ exit 1; }" ERR +set -o errtrace # Trap in functions. + +function info () { echo "$*" 1>&2; } + +exclude=() # Array of excluded directories. +depth=1 + +while [ $# -gt 0 ]; do + case $1 in + -x) + shift + exclude+=("${1%/}") + shift + ;; + -n) + shift + depth="$1" + shift + ;; + *) + break + ;; + esac +done + +# Find all the top-level directories that looks like git repositories. +# +dirs=() +for d in $(find . -mindepth 1 -maxdepth "$depth" -type d -printf '%P\n' | sort); do + if [ -d "$d/.git" ]; then + dirs+=("$d") + fi +done + +# Run the command for each of them. +# +for d in "${dirs[@]}"; do + for e in "${exclude[@]}"; do + if [[ "$d/" =~ ^"$e/" ]]; then + d= + break + fi + done + + if [ -n "$d" ]; then + info "$d/" + git -C "$d" "${@}" + fi +done |