-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathclean-checkout.sh
64 lines (56 loc) · 1.83 KB
/
clean-checkout.sh
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
#!/usr/bin/env bash
#/
#/ Clean checkout of a branch/tag/commit including all submodules
#/ Attention: This is going to delete all local changes!
#/
#/ Usage: git $KIT_ID clean-checkout <options> <branch>
#/
#/ <options> will be passed to the git clean command, see git-clean reference
#/ for available options (-d --force --quiet are passed by default)
#/ <branch> is expected to be the last argument
#/
#/ Example: git ask clean-checkout master
#/
set -e
# check if there is at least one argument passed to the command
if [ $# -lt 1 ]; then
echo "No branch/commit specified"
exit 1
fi
function execute_with_retry {
COMMAND=$1
RETRIES=7 # longest continuous wait should be 64s (2**6)
COUNT=1 # first try after 4s, if needed
RET=1 # make command overwrite this
while [ $COUNT -lt $RETRIES ]; do
set +e
$COMMAND
RET=$?
set -e
if [ $RET -eq 0 ]; then
break
fi
COUNT=$((COUNT+1))
DELAY=$((2**COUNT))
sleep $DELAY
done
if [ $RET -gt 0 ]; then
echo "'$COMMAND' failed with exit code '$RET'"
exit $RET
fi
}
# read branch and options from the arguments, branch is expected to be the last argument
REF=${!#}
OPTIONS=${@:1:$#-1}
# fetch latest changes from all remotes
# cleanup all refs that no longer exist in the remote:
# * could avoid name collisions on case insensitive file systems
execute_with_retry "git fetch --all --force --prune"
# checkout branch and update submodules
git checkout --force $REF
git submodule sync --recursive
execute_with_retry "git submodule update --force --init --recursive"
# clean up repo and submodules
git clean -d --force --quiet $OPTIONS
git submodule foreach --recursive git clean -d --force --quiet $OPTIONS
git submodule foreach --recursive git reset --hard HEAD