A small script to check git repositories in workspace and their submodules. Checks if all submodules have same remote and there is a tag in the submodule for the containing project.
#!/bin/sh
function checkSubmodules() {
echo "Checking submodules..."
local PHC="\033[44;1;37m" # project title color
local THC="\033[44;1;37m" # tag title color
local RHC="\033[44;1;37m" # remote title color
local PC="\033[1;34m" # project color
local MC="\033[0;32m" # module color
local TC="\033[1;33m" # tag color
local RC="\033[1;36m" # remote color
local EC="\033[1;31m" # error color
local HC="\033[1;37m" # highlight color
local NC="\033[0m" # no color
pl=0
tl=0
rl=0
for directory in $(ls); do
if [ -d $directory ] && [ $(expr length $directory) -gt $pl ]; then
pl=$(expr length $directory)
fi
if [ -d $directory ] && [ -d $directory/.git ]; then
cd $directory
tag=$(git remote -v | grep -E "^origin.*\(fetch\)$" | sed -r 's/origin\t[a-z]+:\/\/([^@]+@)?[^\/]+\/(.*)(\.git|[^\.][^g][^i][^t]) \(fetch\)/\2/')
if [ ! -z "$tag" ] && [ $(expr length $tag) -gt $tl ]; then
tl=$(expr length $tag)
fi
remote=$(git remote -v | grep -E "^origin.*\(fetch\)$" | sed -r 's/origin\t([a-z]+:\/\/([^@]+@)?[^\/]+)\/.*(\.git|[^\.][^g][^i][^t]) \(fetch\)/\1/')
if [ ! -z "$remote" ] && [ $(expr length $remote) -gt $rl ]; then
rl=$(expr length $remote)
fi
cd ..
fi
done
printf "${PHC}%-${pl}s${NC} ${THC}%-${tl}s${NC} ${RHC}%-${rl}s${NC}\n" " PROJECT / SUBMODULE" " TAG" " REMOTE"
for directory in $(ls); do
if [ -d $directory ] && [ ! -d $directory/.git ]; then
echo -e "${PC}${directory}${NC} is not a GIT repository."
elif [ -d $directory ]; then
cd $directory
tag=""
remote=""
while [ -z "$tag" ]; do
tag=$(git remote -v | grep -E "^origin.*\(fetch\)$" | sed -r 's/origin\t[a-z]+:\/\/([^@]+@)?[^\/]+\/(.*)(\.git|[^\.][^g][^i][^t]) \(fetch\)/\2/')
remote=$(git remote -v | grep -E "^origin.*\(fetch\)$" | sed -r 's/origin\t([a-z]+:\/\/([^@]+@)?[^\/]+)\/.*(\.git|[^\.][^g][^i][^t]) \(fetch\)/\1/')
if [ -z "$tag" ]; then
echo -e "${EC}Could not detect tag for ${PC}${directory}${EC} project!${NC}" >&2
response="";
while [ "$response" != "c" ]; do
read -p " what next? (${HC}C${NC})ontinue, (${HC}S${NC})hell, (${HC}Q${NC})uit" -n1 response
if [ "$response" = "q" ]; then
exit 1
elif [ "$response" = "s" ]; then
$SHELL
fi
done
fi
done
printf "${PC}%-${pl}s${NC} ${TC}%-${tl}s${NC} ${RC}%-${rl}s${NC}\n" $directory $tag $remote
IFS="
"
for submodule in $(git submodule); do
if echo $submodule | grep -E "^\-.*"; then
subname=$(echo $submodule | sed -r 's/\-[0-9a-f]{40}\ ([^\ ]+)/\1/')
git submodule init $subname
git submodule update $subname
fi
done
sl=$(expr $pl - 4)
tagdesc=""
for submodule in $(git submodule); do
if echo $submodule | grep -E "^.[0-9a-f]{40}\ ([^\ ]+)\ \((.*)\)" > /dev/null; then
parts=$(echo $submodule | sed -r 's/.[0-9a-f]{40}\ ([^\ ]+)\ \((.*)\)/\1 \2/')
subdir=$(echo $parts | cut -d" " -f1)
pardir=$(echo $subdir | sed -r 's/[^\/]+/../g')
subtag=$(echo $parts | cut -d" " -f2)
cd $subdir
subrem=$(git remote -v | grep -E "^origin.*\(fetch\)$" | sed -r 's/origin\t([a-z]+:\/\/[^@]+@[^\/]+)\/.*(\.git)?.*/\1/')
printf " - ${MC}%-${sl}s${NC} ${TC}%-${tl}s${NC} ${RC}%-${rl}s${NC}\n" $subdir $subtag $subrem
if [ "$subrem" != "$remote" ]; then
echo -e " Remote of the containing ${PC}${directory}${NC} project (${RC}${remote}${NC}) differs from remote of the ${MC}${subdir}${NC} submodule (${RC}${subrem}${NC})!" >&2
$SHELL
fi
if [ "$subtag" != "$tag" ]; then
echo -e " Tag ${TC}${tag}${NC} does not match ${MC}${subdir}${NC} submodule tag (${TC}${subtag}${NC})."
while [ -z $tagdesc ]; do
read -p " Enter the description of the ${TC}${tag}${NC} tag: " tagdesc
done
git fetch
git tag -fa $tag -m "$tagdesc"
git push --tags
git lp
fi
cd $pardir
else
echo -e "${EC} Wrong submodule ${MC}${submodule}${EC}!${NC}" >&2
response="";
while [ "$response" != "c" ]; do
read -p " What next? (${HC}C${NC})ontinue, (${HC}S${NC})hell, (${HC}Q${NC})uit" -n1 response;
if [ "$response" = "q" ]; then
exit 1
elif [ "$response" = "s" ]; then
$SHELL
fi
done
fi
done
cd ..
fi
done
}
checkSubmodules