]> git.wh0rd.org Git - home.git/blob - .bin/r
skip repos that are in the middle of a rebase
[home.git] / .bin / r
1 #!/bin/bash
2 g() { git "$@"; }
3 err() { printf '%b\n' "$*" 1>&2; exit 1; }
4 vr() { echo "$@"; "$@"; }
5
6 case $1 in
7 ""|-*) ;;
8 l)
9         cmd=list
10         shift
11         ;;
12 s)
13         cmd=sync
14         shift
15         ;;
16 *)
17         cmd=$1
18         shift
19         acmd=$(git config --get "alias.${cmd}" | sed 's: -.*::')
20         ;;
21 esac
22
23 mj_init() {
24         pipe=$(mktemp)
25         rm -f "${pipe}"
26         mkfifo "${pipe}"
27         exec {ctlfd}<>"${pipe}"
28         rm -f "${pipe}"
29         jobs=0
30         jobs_max=${1:-$(getconf _NPROCESSORS_ONLN)}
31 }
32 _mj_child() { echo ${BASHPID} $? >&${ctlfd} ; }
33 mj_child() {
34         (
35         "$@"
36         _mj_child
37         ) &
38         mj_post_child
39 }
40 mj_post_child() {
41         : $(( ++jobs ))
42         if [[ ${jobs} -eq ${jobs_max} ]] ; then
43                 read -r -u ${ctlfd} pid ret
44                 : $(( --jobs ))
45         fi
46 }
47 mj_finish() {
48         wait
49 }
50
51 repo_root() {
52         local root=${PWD}
53         while [[ ! -d ${root}/.repo && ${root} != "/" ]] ; do
54                 root=${root%/*}
55         done
56         echo "${root}"
57 }
58
59 case ${acmd:-${cmd}} in
60 rebase)
61         if [[ $1 == "all" ]] ; then
62                 shift
63                 if [[ $# -eq 0 ]] ; then
64                         root=$(repo_root)
65                         mj_init
66                         while read -a line ; do
67                                 dir=${line[0]}
68                                 proj=${line[2]}
69                                 cd "${root}/${dir}"
70                                 (
71                                 out=$(env _proj=${proj} r rb all . 2>&1)
72                                 [[ -n ${out} ]] && echo "${out}"
73                                 _mj_child
74                                 ) &
75                                 mj_post_child
76                         done < <(r l)
77                         mj_finish
78                         exit 0
79                         #exec r forall -p -c 'r rb all .' </dev/null
80                 fi
81
82                 branches=$(g b | awk '
83                         {
84                                 if ($0 ~ "^[*] *[(]no branch[)]") {
85                                         next
86                                 } else if ($1 == "*") {
87                                         b = $2
88                                 } else {
89                                         list = list $1 " "
90                                 }
91                         }
92                         END { print list b }')
93                 [[ -z ${branches} ]] && exit 0
94
95                 eval $(bash-colors --env)
96                 #echo "${GOOD}### ${PWD}${NORMAL}"
97                 # Skip if rebase is in progress.
98                 if [[ -e .git/rebase-merge/interactive ]] ; then
99                         echo "# ${_proj}: skipping due to active rebase"
100                         exit 1
101                 fi
102                 for b in ${branches} ; do
103                         #echo " ${HILITE}### $b${NORMAL}"
104                         g co -q $b || exit 1
105                         if ! r rb -q "$@" ; then
106                                 g rb-a
107                         fi
108                 done
109                 exit 0
110         fi
111         ;;
112 sb-push)
113         sync_branch="v"
114
115         root=$(repo_root)
116         cd "${root}" || exit 1
117
118         if [[ ! -e .repo/sandbox-url ]] ; then
119                 err "Please configure remote url base in ${root}/.repo/sandbox-url"
120         fi
121         remote=$(<.repo/sandbox-url) || exit 1
122
123         echo "pushing projects from ${root}"
124
125         # ssh servers do not like it when you hammer them :)
126         #       Received disconnect from 74.125.248.80: 7: Too many concurrent connections
127         #       fatal: The remote end hung up unexpectedly
128         mj_init 16
129
130         rlist=$(r list)
131         tcnt=$(echo "${rlist}" | wc -l)
132         cnt=1
133         while read line ; do
134                 line=( ${line} )
135                 path=${line[0]}
136                 export GIT_DIR=${path}/.git
137                 proj=${line[2]}
138                 printf '### (%*i/%i %3i%%) %s\n' \
139                         ${#tcnt} $((cnt++)) ${tcnt} $(( cnt * 100 / tcnt )) ${proj}
140                 src="${sync_branch}"
141                 g l -1 ${src} >& /dev/null || src=
142                 mj_child g push --force ${remote}/${proj} ${src}:refs/sandbox/${USER}/${sync_branch} >/dev/null
143         done < <(r list)
144         mj_finish
145
146         exit 0
147         ;;
148 g-push)
149         # For the times when repo is being stupid, push directly to gerrit myself.
150         if ! branch=$(g symbolic-ref -q HEAD) ; then
151                 err "could not figure out active branch"
152         fi
153         branch=${branch#refs/heads/}
154         if ! remote_branch=$(g cfg --get "branch.${branch}.merge") ; then
155                 err "could not figure out remote branch"
156         fi
157         remote_branch=${remote_branch#refs/heads/}
158
159         reviewers=""
160         while [[ $# -gt 0 ]] ; do
161                 case $1 in
162                 --re)
163                         reviewers=$2
164                         shift
165                         ;;
166                 *)
167                         err "unknown option: $1"
168                         ;;
169                 esac
170                 shift
171         done
172
173         git_args=()
174         if [[ -n ${reviewers} ]] ; then
175                 reviewers=( ${reviewers//,/ } )
176                 git_args+=( "--receive-pack=git receive-pack ${reviewers[*]/#/--reviewer=}" )
177         fi
178
179         for remote in cros-internal cros origin ; do
180                 if g cfg --get "remote.${remote}.url" >/dev/null ; then
181                         vr git push "${git_args[@]}" ${remote} ${branch}:refs/for/${remote_branch}
182                         exit $?
183                 fi
184         done
185         err "could not figure out remote to push to"
186         ;;
187 sync)
188         set -- -j16 "$@"
189         ;;
190 upload)
191         args=()
192         while [[ $# -gt 0 ]] ; do
193                 case $1 in
194                 --re)
195                         if [[ $2 == *"OWNERS" ]] ; then
196                                 owners=$(awk -F'@' '{list = list "," $1} END {print substr(list, 2)}' "$2")
197                                 if [[ -z ${owners} ]] ; then
198                                         err "cannot find OWNERS list"
199                                 else
200                                         echo "Auto setting reviewers to: ${owners}"
201                                 fi
202                                 args+=( --re "${owners}" )
203                                 shift 2
204                                 continue
205                         fi
206                         ;;
207                 esac
208                 args+=( "$1" )
209                 shift
210         done
211         set -- "${args[@]}"
212         ;;
213 esac
214
215 exec repo ${acmd:-${cmd}} "$@"