aboutsummaryrefslogtreecommitdiff
path: root/foreach-git
diff options
context:
space:
mode:
Diffstat (limited to 'foreach-git')
-rwxr-xr-xforeach-git64
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