Skip to content

Commit 1313f7e

Browse files
committed
Initial commit for this small utility
Given I often need to run a same Git command over a bunch of subdirectories, I developed this small Git addon as an helper for this task. I used it since one year for now, did a small refactoring on it, and it’s time now to issue it and properly version-control it.
0 parents  commit 1313f7e

File tree

3 files changed

+160
-0
lines changed

3 files changed

+160
-0
lines changed

LICENSE

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2+
Version 2, December 2004
3+
4+
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
5+
6+
Everyone is permitted to copy and distribute verbatim or modified
7+
copies of this license document, and changing it is allowed as long
8+
as the name is changed.
9+
10+
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11+
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12+
13+
0. You just DO WHAT THE FUCK YOU WANT TO.

README.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
git-iterate
2+
===========
3+
4+
If you have to repeat a same Git operation over a bunch of subdirectories (e.g. 'status' or 'branch -vv'), this small Git addon is dedicated to this task.
5+
6+
Examples:
7+
```
8+
git iterate -- status
9+
git iterate -q mydir1 mydir2 -- fetch --all
10+
```
11+
12+
Syntax
13+
------
14+
15+
General syntax:
16+
```
17+
git iterate [-q|--quiet] [DIR1] [DIR2] [DIRS...] -- SUBCOMMAND [OPTIONS]
18+
```
19+
20+
* -q: [optional] Remove all non-error output
21+
* --quiet: [optional] Remove the names of the directories in which Git is currently running
22+
* DIR1, DIR2, ...: [optional] Subdirectories names where the Git subcommand must be run, by default current directory
23+
* SUBCOMMAND [OPTIONS]: classical Git subcommand ('status', 'fetch --all', 'pull', etc.)
24+
25+
License
26+
-------
27+
28+
* License: WTFPL 2.0
29+
* Author: Seb35 - Sébastien Beyou

git-iterate

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/bin/bash
2+
#
3+
# Execute Git commands on multiple directories and subdirectories
4+
# > git iterate [-v|-V] DIR1 DIR2 ... -- GIT_COMMAND ...
5+
#
6+
# Parameters:
7+
# -q: Remove all non-error output
8+
# --quiet: Remove announcement of the directories in which there are operations
9+
# DIR*: list of super-directories, Git commands will be executed on each valid sub-directory
10+
# GIT_COMMAND and next parameters: Git commands to be executed on each Git directory
11+
#
12+
# License: WTFPL 2.0 - Seb35
13+
14+
IFS=$'\n'
15+
16+
function search_git_folders() {
17+
git --git-dir="$1" branch >/dev/null 2>&1
18+
if [ $? = 0 ]
19+
then
20+
echo "$1"
21+
else
22+
git --git-dir="$1/.git" branch >/dev/null 2>&1
23+
if [ $? = 0 ]
24+
then
25+
echo "$1"
26+
else
27+
for folder in $(find "$1" -mindepth 1 -maxdepth 1 -type d)
28+
do
29+
search_git_folders "$folder"
30+
done
31+
fi
32+
fi
33+
}
34+
35+
# Catch "verbose" option
36+
quiet="false"
37+
if [ "$1" = "-q" ]
38+
then
39+
quiet="true"
40+
shift
41+
elif [ "$1" = "--quiet" ]
42+
then
43+
quiet="moderate"
44+
shift
45+
fi
46+
47+
# Get folders
48+
folders=""
49+
foreach="false"
50+
for folder in "$@"
51+
do
52+
shift
53+
if [ "$folder" = "--" ]
54+
then
55+
break
56+
elif [ "$folder" = "foreach" ]
57+
then
58+
foreach="true"
59+
break
60+
fi
61+
folders="$folders
62+
$folder"
63+
done
64+
65+
# If no folder is given, use local directory (recursively)
66+
if [ "$folders" = "" ]
67+
then
68+
folders=*
69+
fi
70+
71+
# Iterate over each folder
72+
first="true"
73+
for folder in $folders
74+
do
75+
folders=$(search_git_folders "$folder")
76+
for git_folder in $folders
77+
do
78+
cd "$git_folder"
79+
if [ "$quiet" = "true" ]
80+
then
81+
if [ "$foreach" = "false" ]
82+
then
83+
errors=$(git $@ 2>&1)
84+
else
85+
errors=$($@ 2>&1)
86+
fi
87+
if [ "$?" != 0 ]
88+
then
89+
if [ "$first" = "false" ]
90+
then
91+
echo >&2
92+
fi
93+
first="false"
94+
echo $git_folder >&2
95+
echo "$errors" >&2
96+
echo "Error $? in $git_folder" >&2
97+
fi
98+
else
99+
if [ "$quiet" != "moderate" ]
100+
then
101+
echo -e "\033[1m$git_folder\033[0m"
102+
fi
103+
if [ "$foreach" = "false" ]
104+
then
105+
git $@
106+
errors="$?"
107+
else
108+
eval $@
109+
errors="$?"
110+
fi
111+
if [ "$errors" != 0 ]
112+
then
113+
echo "Error $errors in $git_folder" >&2
114+
fi
115+
fi
116+
cd "$OLDPWD"
117+
done
118+
done

0 commit comments

Comments
 (0)