#! /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