dont rely on cron and try sending mails directly from the cron script
[infrastructure.git] / scripts / git-mirror.sh
1 #!/bin/bash
2
3 ADMINS="Talip-Baris.Metin@inria.fr"
4 MIRROR_GIT="git://git.planet-lab.org"
5 MASTER_GIT="/git"
6 LOCAL_MIRROR_DIR="/git-mirror"
7 QUIET=0
8 FAILED=0
9
10 function msg () {
11     if [ $QUIET -eq 0 ]
12     then
13         echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx $@"
14     fi
15 }
16
17 function error () {
18     for admin in $ADMINS
19     do
20         echo "[ERROR] xxxxxxxxxxx  $@" | mail -s "$@" $admin
21     done
22 }
23
24 function run () {
25     if [ $QUIET -eq 1 ]
26     then
27         COMMAND="$1 &> /dev/null"
28     else
29         COMMAND="$1"
30         msg $COMMAND
31     fi
32     REPO=$2
33
34     pushd ${REPO} > /dev/null
35     eval $COMMAND
36     if [ $? -ne 0 ]
37     then
38         FAILED=1
39     fi
40     popd > /dev/null
41 }
42
43 function run_ignore_errors () {
44     OLD_FAILED=$FAILED
45     run "$1" "$2"
46     FAILED=$OLD_FAILED
47 }
48
49 function merge_all_branches () {
50     NAME=$1
51     REMOTE=$2
52     REPO_DIR=$3
53
54     pushd $REPO_DIR > /dev/null
55     BRANCHES=$(git branch -r | grep $REMOTE | grep -v HEAD | sed "s/.*\///g" | grep -v master)
56     popd > /dev/null
57
58     run "git checkout master" ${REPO_DIR}
59     run "git merge --ff $REMOTE/master" ${REPO_DIR}
60     for BRANCH in $BRANCHES ; do
61         run_ignore_errors "git branch $BRANCH $REMOTE/$BRANCH" ${REPO_DIR}
62         run "git checkout $BRANCH" ${REPO_DIR}
63         run "git merge --ff $REMOTE/$BRANCH" ${REPO_DIR}
64     done
65 }
66
67 function push_all_branches () {
68     NAME=$1
69     REMOTE=$2
70     REPO_DIR=$3
71
72     pushd $REPO_DIR > /dev/null
73     BRANCHES=$(git branch -r | grep $REMOTE | grep -v HEAD | sed "s/.*\///g" | grep -v master)
74     popd > /dev/null
75
76     run "git push $REMOTE master:master" ${REPO_DIR}
77     for BRANCH in $BRANCHES ; do
78         run "git push $REMOTE $BRANCH:$BRANCH" ${REPO_DIR}
79     done
80 }
81
82 function mirror () {
83     for arg in "$@" ; do
84         FAILED=0   # reset previous failure if any
85
86         NAME=$(basename ${arg} | sed s/.git$//g)
87         GIT_NAME=${NAME}.git
88         REPO_DIR=${LOCAL_MIRROR_DIR}/${NAME}
89         MIRROR_REPO=${MIRROR_GIT}/${GIT_NAME}
90         MASTER_REPO=${MASTER_GIT}/${GIT_NAME}
91
92
93         # if there is no remote repository it may be that we only have
94         # the repository locally and don't need to mirror
95         git ls-remote $MIRROR_REPO &> /dev/null
96         if [ $? -eq 0 ]
97         then
98             if [ -d ${REPO_DIR} ]
99             then
100                 msg "pulling from ${NAME}"
101                 run "git fetch origin --tags" ${REPO_DIR}
102                 run "git fetch origin" ${REPO_DIR}
103                 merge_all_branches $NAME origin $REPO_DIR
104                 if [ $? -ne 0 ]
105                 then
106                     error "Can not fetch from ${MASTER_REPO}"
107                 fi
108             else
109                 msg "mirroring ${NAME} for the first time"
110                 run "git clone ${MIRROR_REPO}" ${LOCAL_MIRROR_DIR}
111                 run "git remote add local_master ${MASTER_REPO}" ${REPO_DIR}
112             fi
113
114             msg "pushing ${NAME} to local master"
115             run "git fetch local_master --tags" ${REPO_DIR}
116             run "git fetch local_master" ${REPO_DIR}
117             merge_all_branches $NAME local_master $REPO_DIR
118             if [ $FAILED -ne 0 ]
119             then
120                 error "git-mirror.sh failed on ${MIRROR_REPO}"
121             else
122                 run "git push --tags local_master" ${REPO_DIR}
123                 push_all_branches $NAME local_master $REPO_DIR
124             fi
125         fi
126     done
127 }
128
129
130 while getopts ":hq" opt
131 do
132   case $opt in
133       q)
134           QUIET=1
135           break
136           ;;
137       h)
138           echo "USAGE: $0 [-q] REPONAME*"
139           exit 1
140           ;;
141       \?)
142           echo "Invalid option: -$OPTARG" >&2
143           ;;
144   esac
145 done
146
147 shift $((OPTIND-1))
148 mirror $@
149