-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsubmodules
executable file
·133 lines (119 loc) · 2.93 KB
/
submodules
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env bash
# Manages git submodules. Check the help for more info.
set -e
set -u
set -o pipefail
# Ansi escape codes
RESET="\e[0m"
ITALIC="\e[3m"
BOLD="\e[1m"
YELLOW="\e[33m"
INDENT="\r\t\t\t\t\t"
# root of the repository
root="$(dirname "$(dirname "$(realpath -s "${BASH_SOURCE[0]}")")")/"
cd "$root"
# Shows help and exits with $1
help() {
(
echo "Usage: ${0} <subcommand>"
echo
echo "Subcommands are:"
echo "- help: Show this help"
echo "- fix: Try to fix all submodules by updating and initializing them"
echo " Optional parameters: Paths to submodules - omit for all submodules"
echo "- updatable: List updatable submodules"
echo "- notMaster: List submodules where the current commit is not on origin/master"
echo "- update: Update a submodule (or multiple) to origin/master. With extra force"
echo " Mandatory parameters: Paths to submodules"
) >&2
exit "${1}"
}
# Runs a git command in the global repository context
runGit() {
git --git-dir="${root}/.git" --work-tree="${root}" "${@}"
}
# Runs a git command in the context of the submodule $1
runGitSubmodule() {
submod="${1}"
shift
git --git-dir="${root}/.git/modules/${submod}" --work-tree="${root}/${submod}" "${@}"
}
# Tries to fix submodules
fix() {
runGit submodule absorbgitdirs
runGit submodule update --init --recursive "${@}"
}
# Fetch all submodules parallel
fetch_submodules() {
IFS=$'\n'
echo "Fetch all submodules"
while read -r module_str; do
IFS=' ' read -ra module <<< "$module_str"
cd "${module[1]}" || exit 1
git fetch &
cd "$root" || exit 1
done < <(git submodule status)
wait
}
# Check all submodules for new upstream commits
updatable() {
IFS=$'\n'
fetch_submodules
while read -r module_str; do
IFS=' ' read -ra module <<< "$module_str"
if [ "${module[0]:0:1}" = "+" ]; then
echo -e "$ITALIC$YELLOW${module[1]}$INDENT$RESET$BOLD$YELLOW is out of sync\e[0m"
fi
done < <(git submodule status)
}
# Try to find submodules that are not on master
notMaster() {
IFS=$'\n'
fetch_submodules
while read -r module_str; do
IFS=' ' read -ra module <<< "$module_str"
if ! echo "${module[2]}"|grep -q "master"; then
echo -e "$ITALIC$YELLOW${module[1]}$INDENT$RESET$BOLD$YELLOW is not up to date\e[0m"
elif [ "${module[0]:0:1}" = "+" ]; then
echo -e "$ITALIC$YELLOW${module[1]}$INDENT$RESET$BOLD$YELLOW is out of sync\e[0m"
fi
done < <(git submodule status)
}
# Update a submodule to origin/master
update() {
if [ "${#}" -lt 1 ]; then
help 1
fi
for submod in "${@}"; do
runGitSubmodule "${submod}" fetch origin master
runGitSubmodule "${submod}" checkout master
runGitSubmodule "${submod}" reset --hard origin/master
runGit add "${submod}"
done
}
# Parameter stuff
if [ "${#}" -lt 1 ]; then
help 1
fi
subcommand="${1}"
shift
case "${subcommand}" in
help)
help 0
;;
fix)
fix "${@}"
;;
updatable)
updatable "${@}"
;;
notMaster)
notMaster "${@}"
;;
update)
update "${@}"
;;
*)
help 1
;;
esac