]> de.git.xonotic.org Git - xonotic/xonotic.git/blob - all
fix the time reports
[xonotic/xonotic.git] / all
1 #!/bin/sh
2 # vim: filetype=zsh
3
4 set -e
5 if [ -n "$ZSH_VERSION" ]; then
6         setopt SH_WORD_SPLIT
7 fi
8 if [ -z "$ECHO" ]; then
9         if echo "\\\\" | grep .. >/dev/null; then
10                 ECHO=echo
11         else
12                 ECHO=`which echo`
13         fi
14 fi
15
16 # I use this in EVERY shell script ;)
17 LF="
18 "
19 ESC="\e"
20
21 d00=`pwd`
22 while ! [ -f ./all ]; do
23         if [ x"`pwd`" = x"/" ]; then
24                 $ECHO "Cannot find myself."
25                 $ECHO "Please run this script with the working directory inside a Xonotic checkout."
26                 exit 1
27         fi
28         cd ..
29 done
30 export d0=`pwd`
31 SELF="$d0/all"
32
33 # If we are on WINDOWS:
34 case "$0" in
35         all|*/all)
36                 case "`uname`" in
37                         MINGW*|Win*)
38                                 # Windows hates users. So this script has to copy itself elsewhere first...
39                                 cp "$SELF" ../all.xonotic.sh
40                                 export WE_HATE_OUR_USERS=1
41                                 exec ../all.xonotic.sh "$@"
42                                 ;;
43                 esac
44                 ;;
45 esac
46
47 msg()
48 {
49         $ECHO >&2 "$ESC""[1m$*$ESC""[m"
50 }
51
52 self=`git hash-object "$SELF"`
53 checkself()
54 {
55         self_new=`git hash-object "$SELF"`
56         if [ x"$self" != x"$self_new" ]; then
57                 msg "./all has changed."
58                 if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
59                         msg "Rerunning the requested operation to make sure."
60                         export XONOTIC_FORBID_RERUN_ALL=1
61                         exec "$SELF" "$@"
62                 else
63                         msg "Please try $SELF update, and then retry your requested operation."
64                         exit 1
65                 fi
66         fi
67         return 0
68 }
69
70 verbose()
71 {
72         msg "+ $*"
73         "$@"
74 }
75
76 visible_repo_name()
77 {
78         case "$1" in
79                 .)
80                         $ECHO "the root directory"
81                         ;;
82                 *)
83                         $ECHO "\"$1\""
84                         ;;
85         esac
86 }
87
88 check_mergeconflict()
89 {
90         if git ls-files -u | grep ' 1   '; then
91                 $ECHO
92                 $ECHO "MERGE CONFLICT."
93                 $ECHO "change into the \"$1\" project directory, and then:"
94                 $ECHO "- edit the files mentioned above with your favorite editor,"
95                 $ECHO "  and fix the conflicts (marked with <<<<<<< blocks)"
96                 $ECHO "- for binary files, you can select the files using"
97                 $ECHO "  git checkout --ours or git checkout --theirs"
98                 $ECHO "- when done with a file, 'git add' the file"
99                 $ECHO "- when done, 'git commit'"
100                 $ECHO
101                 exit 1
102         fi
103 }
104
105 yesno()
106 {
107         yesno=
108         while [ x"$yesno" != x"y" -a x"$yesno" != x"n" ]; do
109                 eval "$2"
110                 $ECHO "$1"
111                 if ! IFS= read -r yesno; then
112                         yesno=n
113                         break
114                 fi
115         done
116         [ x"$yesno" = x"y" ]
117 }
118
119 enter()
120 {
121         $2 cd "$1" || exit 1
122         check_mergeconflict "$1"
123 }
124
125 repos_urls="
126 .                             |                                                   | master         |
127 data/xonotic-data.pk3dir      |                                                   | master         |
128 data/xonotic-music.pk3dir     |                                                   | master         |
129 data/xonotic-nexcompat.pk3dir |                                                   | master         | no
130 darkplaces                    |                                                   | div0-stable    | svn
131 netradiant                    |                                                   | master         |
132 div0-gittools                 |                                                   | master         | no
133 d0_blind_id                   |                                                   | master         |
134 data/xonotic-maps.pk3dir      |                                                   | master         |
135 mediasource                   |                                                   | master         | no
136 fteqcc                        |                                                   | xonotic-stable | noautocrlf
137 "
138 # todo: in darkplaces, change repobranch to div0-stable
139
140 repos=`$ECHO "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
141
142 base=`git config remote.origin.url`
143 case "$base" in
144         */xonotic.git)
145                 base=${base%xonotic.git}
146                 ;;
147         *)
148                 $ECHO "The main repo is not xonotic.git, what have you done?"
149                 exit 1
150                 ;;
151 esac
152 pushbase=`git config remote.origin.pushurl || true`
153 case "$pushbase" in
154         */xonotic.git)
155                 pushbase=${pushbase%xonotic.git}
156                 ;;
157         '')
158                 ;;
159         *)
160                 $ECHO "The main repo is not xonotic.git, what have you done?"
161                 exit 1
162                 ;;
163 esac
164
165 repourl()
166 {
167         repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
168         if [ -n "$repo_t" ]; then
169                 case "$repo_t" in
170                         *://*)
171                                 $ECHO "$repo_t"
172                                 ;;
173                         *)
174                                 $ECHO "$base$repo_t"
175                                 ;;
176                 esac
177         else
178                 if [ x"$1" = x"." ]; then
179                         $ECHO "$base""xonotic.git"
180                 else
181                         $ECHO "$base${1##*/}.git"
182                 fi
183         fi
184 }
185
186 repopushurl()
187 {
188         [ -n "$pushbase" ] || return 0
189         repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
190         if [ -n "$repo_t" ]; then
191                 case "$repo_t" in
192                         *://*)
193                                 ;;
194                         *)
195                                 $ECHO "$pushbase$repo_t"
196                                 ;;
197                 esac
198         else
199                 if [ x"$1" = x"." ]; then
200                         $ECHO "$pushbase""xonotic.git"
201                 else
202                         $ECHO "$pushbase${1##*/}.git"
203                 fi
204         fi
205 }
206
207 repobranch()
208 {
209         repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
210         if [ -n "$repo_t" ]; then
211                 $ECHO "$repo_t"
212         else
213                 $ECHO "master"
214         fi
215 }
216
217 repoflags()
218 {
219         $ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 4 | tr -d ' '
220 }
221
222 listrepos()
223 {
224         for d in $repos; do
225                 p="${d%dir}"
226                 f="`repoflags "$d"`"
227                 # if we have the dir, always keep it
228                 if [ -d "$d" ]; then
229                         msg "Repository $d enabled because it already exists"
230                         $ECHO "$d"
231                         continue
232                 fi
233                 # if .yes file exists, always keep it
234                 if [ -f "$d.yes" ]; then
235                         msg "Repository $d enabled by a .yes file"
236                         $ECHO "$d"
237                         continue
238                 fi
239                 # if we have .no file, skip
240                 if [ -f "$d.no" ]; then
241                         msg "Repository $d disabled by a .no file, delete $d.no to enable"
242                         continue
243                 fi
244                 # if we have matching pk3, skip
245                 if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
246                         msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
247                         continue
248                 fi
249                 # if "no" flag is set, skip
250                 case ",$f," in
251                         *,no,*)
252                                 msg "Repository $d disabled by default, create $d.yes to enable"
253                                 continue
254                                 ;;
255                 esac
256                 # default: enable
257                 msg "Repository $d enabled by default"
258                 $ECHO "$d"
259         done
260 }
261
262 repos=`listrepos`
263
264 if [ "$#" = 0 ]; then
265         set -- help
266 fi
267 cmd=$1
268 shift
269
270 case "$cmd" in
271         release|release-*)
272                 export LC_ALL=C
273
274                 release_args="$cmd $*"
275                 msg "*** $release_args: start"
276                 release_starttime=`date +%s`
277                 release_end()
278                 {
279                         release_endtime=`date +%s`
280                         release_deltatime=$(($release_endtime - $release_starttime))
281                         msg "*** $release_args: $release_deltatime seconds"
282                 }
283                 trap release_end EXIT
284                 release_tempstarttime=$release_starttime
285                 release_timereport()
286                 {
287                         release_now=`date +%s` # RELEASE NOW!!!
288                         if [ -n "$*" ]; then
289                                 release_deltatime=$(($release_tempstarttime - $release_now))
290                                 msg "**** $release_args: $*: $release_deltatime seconds"
291                         fi
292                         release_tempstarttime=$release_now
293                 }
294                 ;;
295 esac
296
297 fix_upstream_rebase()
298 {
299         if [ -z "$r_me" ] || [ -z "$r_other" ]; then
300                 return
301         fi
302
303         # one of the two sides of the merge should be remote upstream, or all is fine
304         r_r=`git symbolic-ref HEAD`
305         r_r=${r_r#refs/heads/}
306         r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
307         r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
308         r_bra=${r_bra#refs/heads/}
309         if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
310                 if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
311                         return
312                 fi
313         fi
314
315         r_base=`git merge-base "$r_me" "$r_other"`
316
317         # no merge-base? upstream did filter-branch
318         if [ -n "$r_base" ]; then
319                 # otherwise, check if the two histories are "similar"
320                 r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
321                 r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
322
323                 # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
324                 r_lc_me=`$ECHO "$r_l_me" | wc -l`
325                 r_lc_other=`$ECHO "$r_l_other" | wc -l`
326                 r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
327                 r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
328
329                 if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
330                         if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
331                                 git reset --hard "$r_me"
332                                 git pull --rebase
333                                 return 1
334                         fi
335                 fi
336         fi
337
338         return 0
339 }
340
341 fix_upstream_rebase_mergeok()
342 {
343         r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
344         r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
345         fix_upstream_rebase
346 }
347
348 fix_upstream_rebase_mergefail()
349 {
350         r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
351         r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
352         fix_upstream_rebase
353 }
354
355 fix_git_config()
356 {
357         verbose git config remote.origin.url "$1"
358         if [ -n "$2" ]; then
359                 verbose git config remote.origin.pushurl "$2"
360         else
361                 verbose git config --unset remote.origin.pushurl || true
362         fi
363         verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
364         case ",`repoflags "$d"`," in
365                 *,noautocrlf,*)
366                         verbose git config --unset core.autocrlf || true
367                         ;;
368                 *)
369                         verbose git config core.autocrlf input
370                         ;;
371         esac
372         if [ -z "`git config push.default || true`" ]; then
373                 verbose git config push.default current # or is tracking better?
374         fi
375         verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
376         verbose git config filter.mapclean.smudge "cat"
377 }
378
379 mkzipr()
380 {
381         archive=$1; shift
382         case "$RELEASETYPE" in
383                 release)
384                         sevenzipflags=-mx=9
385                         zipflags=-9
386                         ;;
387                 *)
388                         sevenzipflags=-mx=1
389                         zipflags=-1
390                         ;;
391         esac
392         find "$@" -exec touch -d "2001-01-01 01:01:01 +0000" {} \+ # ugly hack to make the pk3 files rsync-friendly
393         ziplist=`mktemp`
394         find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
395         7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
396         zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
397         rm -f "$ziplist"
398 }
399
400 mkzip()
401 {
402         archive=$1; shift
403         case "$RELEASETYPE" in
404                 release)
405                         sevenzipflags=-mx=9
406                         zipflags=-9
407                         ;;
408                 *)
409                         sevenzipflags=-mx=1
410                         zipflags=-1
411                         ;;
412         esac
413         ziplist=`mktemp`
414         find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
415         7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
416         zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
417         rm -f "$ziplist"
418 }
419
420 mkzip0()
421 {
422         archive=$1; shift
423         zip -0ry "$archive" "$@"
424 }
425
426 mirrorspeed()
427 {
428         # first result is to be ignored, but we use it to check status
429         git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
430         { time -p git ls-remote "$1" refs/heads/master; } 2>&1 >/dev/null | head -n 1 | cut -d ' ' -f 2 | tr -d . | sed 's,^0*,,'
431                 # unit: clock ticks (depends on what "time" returns
432 }
433
434 bestmirror()
435 {
436         pre=$1; shift
437         suf=$1; shift
438
439         if ! { time -p true; } >/dev/null 2>&1; then
440                 msg "Cannot do timing in this shell"
441                 return 1
442         fi
443
444         bestin=
445         bestt=
446         for mir in "$@"; do
447                 case "$mir" in
448                         *:*)
449                                 in=${mir%%:*}
450                                 op=${mir#*:}
451                                 ;;
452                         *)
453                                 in=$mir
454                                 op=
455                                 ;;
456                 esac
457                 m=$pre$in$suf
458                 if t=`mirrorspeed "$m"`; then
459                         if [ -n "$t" ]; then
460                                 tt=$(($t$op)) # fudge factor
461                                 msg "$m -> $t$op = $tt ticks"
462                                 if [ -z "$bestt" ] || [ "$tt" -lt "$bestt" ]; then
463                                         bestin=$in
464                                         bestt=$tt
465                                 fi
466                         else
467                                 msg "$m -> error"
468                         fi
469                 else
470                         msg "$m -> FAIL"
471                 fi
472         done
473         if [ -n "$bestin" ]; then
474                 msg "Best mirror seems to be $pre$bestin$suf"
475                 $ECHO "$bestin"
476         else
477                 return 1
478         fi
479 }
480
481 case "$cmd" in
482         fix_upstream_rebase)
483                 for d in $repos; do
484                         enter "$d0/$d" verbose
485                         verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
486                 done
487                 ;;
488         fix_config)
489                 for d in $repos; do
490                         url=`repourl "$d"`
491                         pushurl=`repopushurl "$d"`
492                         branch=`repobranch "$d"`
493                         if [ -d "$d0/$d" ]; then
494                                 verbose cd "$d0/$d"
495                                 fix_git_config "$url" "$pushurl"
496                                 cd "$d0"
497                         fi
498                 done
499                 ;;
500         keygen)
501                 # enable the ssh URL for pushing
502                 "$SELF" update -N -p
503
504                 if [ -f ~/.ssh/id_rsa.pub ]; then
505                         msg ""
506                         msg "A key already exists and no new one will be generated. If you"
507                         msg "already have done the procedure for getting your key approved, you"
508                         msg "can skip the following paragraph and already use the repository."
509                         msg ""
510                         msg "To get access, your key has to be approved first. For that, visit"
511                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
512                         msg "the \"Support\" tracker in the \"Repository\" category where you"
513                         msg "apply for access and paste the following output into the issue:"
514                         msg ""
515                         msg "`cat ~/.ssh/id_rsa.pub`"
516                         msg ""
517                         msg "Note that you will only have write access to branches that start"
518                         msg "with your user name."
519                 elif [ -f ~/.ssh/id_dsa.pub ]; then
520                         msg ""
521                         msg "A key already exists and no new one will be generated. If you"
522                         msg "already have done the procedure for getting your key approved, you"
523                         msg "can skip the following paragraph and already use the repository."
524                         msg ""
525                         msg "To get access, your key has to be approved first. For that, visit"
526                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
527                         msg "the \"Support\" tracker in the \"Repository\" category where you"
528                         msg "apply for access and paste the following output into the issue:"
529                         msg ""
530                         msg "`cat ~/.ssh/id_dsa.pub`"
531                         msg ""
532                         msg "Note that you will only have write access to branches that start"
533                         msg "with your user name."
534                 else
535                         msg ""
536                         msg "No key has been generated yet. One will be generated now."
537                         msg "If other people are using your computer, it is recommended"
538                         msg "to specify a passphrase. Otherwise you can simply hit ENTER"
539                         msg "when asked for a passphrase."
540                         msg ""
541                         ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
542                         msg ""
543                         msg "To get access, your key has to be approved first. For that, visit"
544                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
545                         msg "the \"Support\" tracker in the \"Repository\" category where you"
546                         msg "apply for access and paste the following output into the issue:"
547                         msg ""
548                         msg "`cat ~/.ssh/id_rsa.pub`"
549                         msg ""
550                         msg "Note that you will only have write access to branches that start"
551                         msg "with your user name."
552                 fi
553                 ;;
554         update|pull)
555                 allow_pull=true
556                 fix_config=false
557                 location=current
558                 while :; do
559                         if [ x"$1" = x"-N" ]; then
560                                 allow_pull=false
561                         elif [ x"$1" = x"-p" ]; then
562                                 fix_config=true
563                                 pushbase=ssh://xonotic@git.xonotic.org/
564                         elif [ x"$1" = x"-ps" ]; then
565                                 fix_config=true
566                                 pushbase=ssh://xonotic@git.xonotic.org/
567                         elif [ x"$1" = x"-ph" ]; then
568                                 fix_config=true
569                                 pushbase=http://git.xonotic.org/login/xonotic/
570                         elif [ x"$1" = x"-s" ]; then
571                                 fix_config=true
572                                 base=ssh://xonotic@git.xonotic.org/
573                         elif [ x"$1" = x"-g" ]; then
574                                 fix_config=true
575                                 base=git://git.xonotic.org/xonotic/
576                         elif [ x"$1" = x"-h" ]; then
577                                 fix_config=true
578                                 base=http://git.xonotic.org/xonotic/
579                         elif [ x"$1" = x"-l" ]; then
580                                 case "$2" in
581                                         nl) ;;
582                                         de) ;;
583                                         us) ;;
584                                         best) ;;
585                                         default) ;;
586                                         *)
587                                                 msg "Invalid location!"
588                                                 msg "Possible locations for the -l option:"
589                                                 msg "  nl (Netherlands, run by merlijn)"
590                                                 msg "  de (Germany, run by divVerent)"
591                                                 msg "  us (United States of America, run by detrate)"
592                                                 msg "  best (find automatically)"
593                                                 msg "  default (currently nl)"
594                                                 exit 1
595                                                 ;;
596                                 esac
597                                 fix_config=true
598                                 location=$2
599                                 shift
600                         else
601                                 break
602                         fi
603                         shift
604                 done
605                 case "$location" in
606                         current)
607                                 if [ x"`git config xonotic.all.mirrorselection 2>/dev/null || true`" != x"done" ]; then
608                                         location=best
609                                 fi
610                                 ;;
611                 esac
612                 case "$location" in
613                         best)
614                                 # if we fetched via ssh://, switch to git:// for fetching and keep using ssh:// for pushing
615                                 case "$base" in
616                                         ssh://*|*/login/*)
617                                                 pushbase=$base
618                                                 base=git://git.xonotic.org/xonotic/
619                                                 ;;
620                                 esac
621                                 newbase=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,:// .git.xonotic.org/,"`
622                                 case "$newbase" in
623                                         *\ *)
624                                                 if location=`bestmirror $newbase"xonotic.git" de us nl:'*6/5'`; then # 20% malus to the NL server to not overload it too much
625                                                         git config xonotic.all.mirrorselection done
626                                                 else
627                                                         location=current
628                                                 fi
629                                                 ;;
630                                         *)
631                                                 location=current
632                                                 ;;
633                                 esac
634                                 ;;
635                 esac
636                 case "$location" in
637                         default)
638                                 location=
639                                 ;;
640                         current)
641                                 case "$base" in
642                                         *://*.git.xonotic.org/*)
643                                                 location=${base%%.git.xonotic.org/*}
644                                                 location=${location##*://}
645                                                 ;;
646                                         *)
647                                                 location=
648                                                 ;;
649                                 esac
650                                 ;;
651                 esac
652                 if [ -n "$location" ]; then
653                         base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
654                         pushbase=`$ECHO "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
655                 else
656                         base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
657                         pushbase=`$ECHO "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
658                 fi
659                 if $fix_config; then
660                         url=`repourl .`
661                         pushurl=`repopushurl .`
662                         fix_git_config "$url" "$pushurl"
663                 fi
664                 if $allow_pull || $fix_config; then
665                         "$SELF" fix_config
666                 fi
667                 for d in $repos; do
668                         url=`repourl "$d"`
669                         pushurl=`repopushurl "$d"`
670                         branch=`repobranch "$d"`
671                         if [ -d "$d0/$d" ]; then
672                                 # if we have .no file, skip
673                                 if [ -f "$d0/$d.no" ]; then
674                                         msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
675                                         continue
676                                 fi
677                                 if $allow_pull; then
678                                         enter "$d0/$d" verbose
679                                         r=`git symbolic-ref HEAD`
680                                         r=${r#refs/heads/}
681                                         if git config branch.$r.remote >/dev/null 2>&1; then
682                                                 if ! verbose git pull; then
683                                                         fix_upstream_rebase_mergefail || true
684                                                         check_mergeconflict "$d"
685                                                         $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
686                                                         read -r DUMMY
687                                                 else
688                                                         fix_upstream_rebase_mergeok || true
689                                                 fi
690                                         fi
691
692                                         cd "$d00"
693                                         checkself "$cmd" "$@"
694                                         cd "$d0/$d"
695                                         verbose git remote prune origin
696                                         cd "$d0"
697                                 fi
698                         else
699                                 verbose git clone "$url" "$d0/$d"
700                                 enter "$d0/$d" verbose
701                                 fix_git_config "$url" "$pushurl"
702                                 if [ "$branch" != "master" ]; then
703                                         verbose git checkout --track -b "$branch" origin/"$branch"
704                                 fi
705                                 cd "$d0"
706                         fi
707                 done
708                 ;;
709         update-maps)
710                 misc/tools/xonotic-map-compiler-autobuild download
711                 ;;
712         checkout|switch)
713                 checkoutflags=
714                 if [ x"$1" = x"-f" ]; then
715                         checkoutflags=-f
716                         shift
717                 fi
718                 remote=$1
719                 branch=$2
720                 if [ -z "$branch" ]; then
721                         case "$remote" in
722                                 origin/*)
723                                         branch=${remote#origin/}
724                                         remote=origin
725                                         ;;
726                                 *)
727                                         branch=$remote
728                                         remote=origin
729                                         ;;
730                         esac
731                 fi
732                 if [ -n "$checkoutflags" ]; then
733                         set -- -f "$@" # to make checkself work again
734                 fi
735                 exists=false
736                 for d in $repos; do
737                         enter "$d0/$d" verbose
738                         b=$branch
739                         if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
740                                 exists=true
741                                 verbose git checkout $checkoutflags "$b"
742                         elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
743                                 exists=true
744                                 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
745                         else
746                                 b=`repobranch "$d"`
747                                 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
748                                         exists=true
749                                         verbose git checkout $checkoutflags "$b"
750                                 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
751                                         exists=true
752                                         verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
753                                 else
754                                         $ECHO "WTF? Not even branch $b doesn't exist in $d"
755                                         exit 1
756                                 fi
757                         fi
758                         cd "$d00"
759                         checkself "$cmd" "$@"
760                         cd "$d0"
761                 done
762                 if ! $exists; then
763                         $ECHO "The requested branch was not found in any repository."
764                 fi
765                 exec "$SELF" branch
766                 ;;
767         branch)
768                 remote=$1
769                 branch=$2
770                 srcbranch=$3
771                 if [ -z "$branch" ]; then
772                         branch=$remote
773                         remote=origin
774                 fi
775                 if [ -z "$branch" ]; then
776                         for d in $repos; do
777                                 enter "$d0/$d"
778                                 r=`git symbolic-ref HEAD`
779                                 r=${r#refs/heads/}
780                                 $ECHO "$d is at $r"
781                                 cd "$d0"
782                         done
783                 else
784                         for d in $repos; do
785                                 dv=`visible_repo_name "$d"`
786                                 enter "$d0/$d" verbose
787                                 if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
788                                         $ECHO "Already having this branch in $dv."
789                                 else
790                                         if yesno "Branch in $dv?"; then
791                                                 if [ -n "$srcbranch" ]; then
792                                                         b=$srcbranch
793                                                 else
794                                                         b=origin/"`repobranch "$d"`"
795                                                         verbose git fetch origin || true
796                                                 fi
797                                                 # TODO do this without pushing
798                                                 verbose git checkout -b "$branch" "$b"
799                                                 verbose git config "branch.$branch.remote" "$remote"
800                                                 verbose git config "branch.$branch.merge" "refs/heads/$branch"
801                                         fi
802                                 fi
803                                 cd "$d0"
804                         done
805                         "$SELF" branch
806                 fi
807                 ;;
808         branches)
809                 for d in $repos; do
810                         cd "$d0/$d" # am in a pipe, shouldn't use enter
811                         git branch -r -v -v | cut -c 3- | sed "s/^(no branch)/(no_branch)/" | sed "s,^,$d ,"
812                         cd "$d0"
813                 done | {
814                         branches_list=
815                         # branches_repos_*=
816                         while read -r d BRANCH REV TEXT; do
817                                 if [ x"$BRANCH" = x"`repobranch "$d"`" ]; then
818                                         continue
819                                 fi
820                                 if [ x"$REV" = x"->" ]; then
821                                         continue
822                                 fi
823                                 BRANCH=${BRANCH#remotes/}
824                                 ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
825                                 branches_list="$branches_list $BRANCH" # TEH SORT MAKEZ IT UNIEQ
826                                 eval "r=\$branches_repos_$ID"
827                                 r="$r $d"
828                                 eval "branches_repos_$ID=\$r"
829                         done
830                         $ECHO -n "$branches_list" | xargs -n 1 $ECHO | sort -u | while IFS= read -r BRANCH; do
831                                 ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
832                                 eval "r=\$branches_repos_$ID"
833                                 printf "%-60s %s\n" "$BRANCH" "$r"
834                                 #$ECHO "$BRANCH: $r"
835                         done
836                 }
837                 ;;
838         merge)
839                 for d in $repos; do
840                         dv=`visible_repo_name "$d"`
841                         enter "$d0/$d" verbose
842                         r=`git symbolic-ref HEAD`
843                         r=${r#refs/heads/}
844                         if git log HEAD..origin/"`repobranch "$d"`" | grep .; then
845                                 # we have uncommitted changes
846                                 if yesno "Could merge from \"`repobranch "$d"`\" into \"$r\" in $dv. Do it?"; then
847                                         if ! verbose git merge origin/"`repobranch "$d"`"; then
848                                                 check_mergeconflict "$d"
849                                                 exit 1 # this should ALWAYS be fatal
850                                         fi
851                                 fi
852                         fi
853                         cd "$d0"
854                 done
855                 ;;
856         push|commit)
857                 submit=$1
858                 for d in $repos; do
859                         dv=`visible_repo_name "$d"`
860                         enter "$d0/$d" verbose
861                         r=`git symbolic-ref HEAD`
862                         r=${r#refs/heads/}
863                         diffdata=`git diff --color HEAD`
864                         if [ -n "$diffdata" ]; then
865                                 # we have uncommitted changes
866                                 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
867                                         verbose git commit -a
868                                 fi
869                         fi
870                         rem=`git config "branch.$r.remote" || $ECHO origin`
871                         bra=`git config "branch.$r.merge" || $ECHO "$r"`
872                         upstream="$rem/${bra#refs/heads/}"
873                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
874                                 upstream="origin/`repobranch "$d"`"
875                         fi
876                         logdata=`git log --color "$upstream".."$r"`
877                         if [ -n "$logdata" ]; then
878                                 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
879                                         verbose git push "$rem" HEAD
880                                 fi
881                         fi
882                         if [ x"$submit" = x"-s" ]; then
883                                 case "$r" in
884                                         */*)
885                                                 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
886                                                 ;;
887                                 esac
888                         fi
889                         cd "$d0"
890                 done
891                 ;;
892         compile)
893                 cleand0=false
894                 cleandp=false
895                 cleanqcc=false
896                 cleanqc=false
897                 compiled0=false
898                 debug=debug
899                 snowleopardhack=false
900                 if [ -z "$CC" ]; then
901                         export CC="gcc -DSUPPORTIPV6"
902                 fi
903                 while :; do
904                         case "$1" in
905                                 -0)
906                                         compiled0=true
907                                         shift
908                                         ;;
909                                 -c)
910                                         cleand0=true
911                                         cleandp=true
912                                         cleanqcc=true
913                                         cleanqc=true
914                                         shift
915                                         ;;
916                                 -r|-p)
917                                         case "$1" in
918                                                 -p)
919                                                         debug=profile
920                                                         ;;
921                                                 -r)
922                                                         debug=release
923                                                         ;;
924                                         esac
925                                         export CC="$CC -g"
926                                         case "`$CC -dumpversion`" in
927                                                 [5-9]*|[1-9][0-9]*|4.[3-9]*|4.[1-9][0-9]*)
928                                                         # gcc 4.3 or higher
929                                                         # -march=native is broken < 4.3
930                                                         export CC="$CC -mtune=native -march=native"
931                                                         ;;
932                                         esac
933                                         if [ -n "$WE_HATE_OUR_USERS" ]; then
934                                                 export CC="$CC -fno-common"
935                                         fi
936                                         shift
937                                         ;;
938                                 *)
939                                         break
940                                         ;;
941                         esac
942                 done
943                 if [ -n "$WE_HATE_OUR_USERS" ]; then
944                         TARGETS="sv-$debug cl-$debug"
945                 elif [ x"`uname`" = x"Darwin" ]; then
946                         case "`uname -r`" in
947                                 ?.*)
948                                         TARGETS="sv-$debug cl-$debug sdl-$debug"
949                                         ;;
950                                 *)
951                                         # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
952                                         snowleopardhack=true
953                                         TARGETS="sv-$debug sdl-$debug"
954                                         ;;
955                         esac
956                         export CC="$CC -fno-reorder-blocks -I$PWD/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks/SDL.framework/Headers -F$PWD/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
957                 else
958                         TARGETS="sv-$debug cl-$debug sdl-$debug"
959                 fi
960                 if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
961                         # if we give the command make the arg "", it will surely fail (invalid filename),
962                         # so better handle it as an empty client option
963                         BAD_TARGETS=" "
964                         shift
965                 elif [ -n "$1" ]; then
966                         BAD_TARGETS=
967                         TARGETS_SAVE=$TARGETS
968                         TARGETS=
969                         for X in $1; do
970                                 case "$X" in
971                                         sdl)
972                                                 TARGETS="$TARGETS sdl-debug"
973                                                 ;;
974                                         agl)
975                                                 TARGETS="$TARGETS cl-debug"
976                                                 if $snowleopardhack; then
977                                                         export CC="$CC -arch i386"
978                                                 fi
979                                                 ;;
980                                         glx|wgl)
981                                                 TARGETS="$TARGETS cl-debug"
982                                                 ;;
983                                         dedicated)
984                                                 TARGETS="$TARGETS sv-debug"
985                                                 ;;
986                                         *)
987                                                 BAD_TARGETS="$BAD_TARGETS $X"
988                                                 ;;
989                                 esac
990                         done
991                         if [ -n "$TARGETS" ]; then # at least a valid client
992                                 shift
993                         else # no valid client, let's assume this option is not meant to be a client then
994                                 TARGETS=$TARGETS_SAVE
995                                 BAD_TARGETS=
996                         fi
997                 fi
998                 if [ -z "$MAKEFLAGS" ]; then
999                         if [ -f /proc/cpuinfo ]; then
1000                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
1001                                 if [ $ncpus -gt 1 ]; then
1002                                         MAKEFLAGS=-j$ncpus
1003                                 fi
1004                         fi
1005                         if [ -n "$WE_HATE_OUR_USERS" ]; then
1006                                 MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
1007                         fi
1008                 fi
1009
1010                 verbose cd "$d0/d0_blind_id"
1011                 if ! $compiled0; then
1012                         # compilation of crypto library failed
1013                         # use binaries then, if we can...
1014                         mkdir -p .libs
1015                         if [ -n "$WE_HATE_OUR_USERS" ]; then
1016                                 verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
1017                                 verbose cp "$d0/misc/buildfiles/win32/libd0_rijndael"-* .libs/
1018                                 verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
1019                         else
1020                                 case "`uname`" in
1021                                         Linux)
1022                                                 case `uname -m` in
1023                                                         x86_64)
1024                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
1025                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_rijndael".* .libs/
1026                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
1027                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
1028                                                                 ;;
1029                                                         *86)
1030                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
1031                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_rijndael".* .libs/
1032                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
1033                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
1034                                                                 ;;
1035                                                         *)
1036                                                                 compiled0=true
1037                                                                 ;;
1038                                                 esac
1039                                                 ;;
1040                                         Darwin)
1041                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
1042                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael".* .libs/
1043                                                 ;;
1044                                         *)
1045                                                 compiled0=true
1046                                                 ;;
1047                                 esac
1048                         fi
1049                 fi
1050                 if $compiled0; then
1051                         if $cleand0; then
1052                                 if [ -f Makefile ]; then
1053                                         verbose make $MAKEFLAGS distclean
1054                                 fi
1055                         fi
1056                         if ! [ -f Makefile ]; then
1057                                 verbose sh autogen.sh
1058                                 verbose ./configure
1059                         fi
1060                         verbose make $MAKEFLAGS
1061                 fi
1062
1063                 verbose cd "$d0/fteqcc"
1064                 if $cleanqcc; then
1065                         verbose make $MAKEFLAGS clean
1066                 fi
1067                 verbose make $MAKEFLAGS
1068
1069                 verbose cd "$d0/data/xonotic-data.pk3dir"
1070                 if $cleanqc; then
1071                         verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
1072                 fi
1073                 verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
1074                 # 4 levels up: data, xonotic-data, qcsrc, server
1075
1076                 verbose cd "$d0/darkplaces"
1077                 if [ x"$BAD_TARGETS" = x" " ]; then
1078                         $ECHO "Warning: invalid empty client, default clients will be used."
1079                 fi
1080                 if $cleandp; then
1081                         verbose make $MAKEFLAGS clean
1082                 fi
1083                 for T in $TARGETS; do
1084                         verbose make $MAKEFLAGS STRIP=: "$@" "$T"
1085                 done
1086                 for T in $BAD_TARGETS; do
1087                         $ECHO "Warning: discarded invalid client $T."
1088                 done
1089
1090                 verbose "$SELF" update-maps
1091                 ;;
1092         run)
1093                 if [ -n "$WE_HATE_OUR_USERS" ]; then
1094                         client=
1095                         export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
1096                 elif [ x"`uname`" = x"Darwin" ]; then
1097                         export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS:$d0/d0_blind_id/.libs"
1098                         export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
1099                         client=-sdl
1100                 else
1101                         export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
1102                         client=-sdl
1103                 fi
1104                 case "$1" in
1105                         sdl|glx|agl|dedicated)
1106                                 client=-$1
1107                                 shift
1108                                 ;;
1109                         wgl)
1110                                 client=
1111                                 shift
1112                                 ;;
1113                 esac
1114                 if ! [ -x "darkplaces/darkplaces$client" ]; then
1115                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
1116                                 client=$client.exe
1117                         else
1118                                 $ECHO "Client darkplaces/darkplaces$client not found, aborting"
1119                                 exit 1
1120                         fi
1121                 fi
1122                 set -- "darkplaces/darkplaces$client" -xonotic "$@"
1123
1124                 # if pulseaudio is running: USE IT
1125                 if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
1126                         if ps -C pulseaudio >/dev/null; then
1127                                 if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
1128                                         export SDL_AUDIODRIVER=pulse
1129                                 fi
1130                         fi
1131                 fi
1132
1133                 binary=$1
1134
1135                 if [ x"$USE_GDB" = x"yes" ]; then
1136                         set -- gdb --args "$@"
1137                 elif [ x"$USE_GDB" != x"no" ] && which gdb >/dev/null 2>&1; then
1138                         set -- gdb --batch -x savecore.gdb --args "$@"
1139                 elif which catchsegv >/dev/null 2>&1; then
1140                         set -- catchsegv "$@"
1141                 fi
1142                 rm -f xonotic.core
1143                 "$@" || true
1144                 if [ -f xonotic.core ]; then
1145                         if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
1146                                 gdb "$binary" xonotic.core
1147                         #elif yesno "You did not want to examine the core dump. Do you want to provide it - including your DarkPlaces checkout - to the Xonotic developers?"; then
1148                         #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
1149                         #       # somehow send it
1150                         #       rm -f xonotic.core.tar.gz
1151                         else
1152                                 $ECHO "The core dump can be examined later by"
1153                                 $ECHO "  gdb $binary xonotic.core"
1154                         fi
1155                         exit 1
1156                 fi
1157                 ;;
1158         each|foreach)
1159                 keep_going=false
1160                 if [ x"$1" = x"-k" ]; then
1161                         keep_going=true
1162                         shift
1163                 fi
1164                 for d in $repos; do
1165                         if verbose cd "$d0/$d"; then
1166                                 if $keep_going; then
1167                                         verbose "$@" || true
1168                                 else
1169                                         verbose "$@"
1170                                 fi
1171                                 cd "$d0"
1172                         fi
1173                 done
1174                 ;;
1175         save-patches)
1176                 outfile=$1
1177                 patchdir=`mktemp -d -t save-patches.XXXXXX`
1178                 for d in $repos; do
1179                         enter "$d0/$d" verbose
1180                         git branch -v -v | cut -c 3- | {
1181                                 i=0
1182                                 while read -r BRANCH REV UPSTREAM TEXT; do
1183                                         case "$UPSTREAM" in
1184                                                 \[*)
1185                                                         UPSTREAM=${UPSTREAM#\[}
1186                                                         UPSTREAM=${UPSTREAM%\]}
1187                                                         UPSTREAM=${UPSTREAM%:*}
1188                                                         TRACK=true
1189                                                         ;;
1190                                                 *)
1191                                                         UPSTREAM=origin/"`repobranch "$d"`"
1192                                                         TRACK=false
1193                                                         ;;
1194                                         esac
1195                                         if [ x"$REV" = x"->" ]; then
1196                                                 continue
1197                                         fi
1198                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
1199                                                 $ECHO "$d" > "$patchdir/$i/info.txt"
1200                                                 $ECHO "$BRANCH" >> "$patchdir/$i/info.txt"
1201                                                 $ECHO "$UPSTREAM" >> "$patchdir/$i/info.txt"
1202                                                 $ECHO "$TRACK" >> "$patchdir/$i/info.txt"
1203                                                 i=$(($i+1))
1204                                         else
1205                                                 rm -rf "$patchdir/$i"
1206                                         fi
1207                                 done
1208                         }
1209                 done
1210                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
1211                 rm -rf "$patchdir"
1212                 ;;
1213         restore-patches)
1214                 infile=$1
1215                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
1216                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
1217                 # detach the head
1218                 for P in "$patchdir"/*/info.txt; do
1219                         D=${P%/info.txt}
1220                         exec 3<"$P"
1221                         read -r d <&3
1222                         read -r BRANCH <&3
1223                         read -r UPSTREAM <&3
1224                         read -r TRACK <&3
1225                         verbose git checkout HEAD^0
1226                         verbose git branch -D "$BRANCH"
1227                         if [ x"$TRACK" = x"true" ]; then
1228                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
1229                         else
1230                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
1231                         fi
1232                         verbose git am "$D"
1233                 done
1234                 rm -rf "$patchdir"
1235                 ;;
1236         admin-merge)
1237                 branch=$1
1238                 only_delete=false
1239                 case "$branch" in
1240                         -d)
1241                                 branch=
1242                                 only_delete=true
1243                                 ;;
1244                 esac
1245                 t=`mktemp`
1246                 report=""
1247                 reportecho()
1248                 {
1249                         report=$report"$*$LF"
1250                         $ECHO "$*"
1251                 }
1252                 reportecho4()
1253                 {
1254                         report=$report"    $*$LF"
1255                         $ECHO "    $*"
1256                 }
1257                 reportdo4()
1258                 {
1259                         o=`"$@" | sed 's/^/    /' || true`
1260                         reportecho "$o"
1261                 }
1262                 for d in $repos; do
1263                         case "$d" in
1264                                 fteqcc)
1265                                         # sorry, fteqcc repo is managed manually
1266                                         continue
1267                                         ;;
1268                         esac
1269                         enter "$d0/$d" verbose
1270                         base="`repobranch "$d"`"
1271                         reportecho "In $d:"
1272                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
1273                                 case "${ref#refs/remotes/origin/}" in
1274                                         "$base")
1275                                                 continue
1276                                                 ;;
1277                                         HEAD|master)
1278                                                 continue
1279                                                 ;;
1280                                         */*)
1281                                                 ;;
1282                                         *)
1283                                                 continue
1284                                                 ;;
1285                                 esac
1286                                 if [ -n "$branch" ]; then
1287                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1288                                                 continue
1289                                         fi
1290                                 fi
1291                                 case "$base" in
1292                                         master)
1293                                                 realbase=$base
1294                                                 ;;
1295                                         *)
1296                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1297                                                 l1=`git rev-list master.."$ref" | wc -l`
1298                                                 if [ $l0 -gt $l1 ]; then
1299                                                         realbase=master
1300                                                 else
1301                                                         realbase=$base
1302                                                 fi
1303                                                 ;;
1304                                 esac
1305                                 reportecho "  Branch $ref:"
1306                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1307                                 logdata=`git log --color "$realbase".."$ref"`
1308                                 if [ -z "$logdata" ]; then
1309                                         reportecho4 "--> not merging, no changes vs master"
1310                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1311                                                 git push origin :"${ref#refs/remotes/origin/}"
1312                                                 reportecho4 "--> branch deleted"
1313                                         fi
1314                                 else
1315                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1316                                         if [ -z "$diffdata" ]; then
1317                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1318                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ $ECHO "$logdata"; } | less -r'; then
1319                                                         git push origin :"${ref#refs/remotes/origin/}"
1320                                                         reportecho4 "--> branch deleted"
1321                                                 fi
1322                                         elif $only_delete; then
1323                                                 reportecho4 "--> skipped in delete-only run"
1324                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1325                                                 reportdo4 $ECHO "$note"
1326                                                 reportecho4 "--> not merging, already had this one rejected before"
1327                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ $ECHO "$logdata"; $ECHO "$diffdata"; } | less -r'; then
1328                                                 git checkout "$realbase"
1329                                                 org=`git rev-parse HEAD`
1330                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1331                                                         git reset --hard "$org"
1332                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1333                                                         reportdo4 cat "$t"
1334                                                         reportecho4 "--> merge failed"
1335                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1336                                                         git reset --hard "$org"
1337                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1338                                                         reportdo4 cat "$t"
1339                                                         reportecho4 "--> compile failed"
1340                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1341                                                         git reset --hard "$org"
1342                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1343                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1344                                                         if [ x"$note" = x"del" ]; then
1345                                                                 git push origin :"${ref#refs/remotes/origin/}"
1346                                                                 reportecho4 "--> test failed, branch deleted"
1347                                                         elif [ -n "$note" ]; then
1348                                                                 reportdo4 $ECHO "$note"
1349                                                                 reportecho4 "--> test failed"
1350                                                         else
1351                                                                 reportecho4 "--> test failed, postponed"
1352                                                         fi
1353                                                 else
1354                                                         # apply crlf, or other cleanup filters (non-behavioural changes)
1355                                                         git reset --hard
1356                                                         find . -type f -exec touch {} \;
1357                                                         git commit -a --amend -C HEAD || true # don't fail if nothing to commit
1358
1359                                                         $ECHO "MERGING"
1360                                                         case ",`repoflags "$d"`," in
1361                                                                 *,svn,*)
1362                                                                         # we do quite a mess here... luckily we know $org
1363                                                                         git fetch # svn needs to be current
1364                                                                         git rebase -i --onto origin/master "$org"
1365                                                                         git svn dcommit --add-author-from
1366                                                                         git reset --hard "$org"
1367                                                                         ;;
1368                                                                 *)
1369                                                                         git push origin HEAD
1370                                                                         ;;
1371                                                         esac
1372                                                         reportecho4 "--> MERGED"
1373                                                         if yesno "Delete original branch \"$ref\"?"; then
1374                                                                 git push origin :"${ref#refs/remotes/origin/}"
1375                                                                 reportecho4 "--> branch deleted"
1376                                                         fi
1377                                                 fi
1378                                         else
1379                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1380                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1381                                                 if [ x"$note" = x"del" ]; then
1382                                                         git push origin :"${ref#refs/remotes/origin/}"
1383                                                         reportecho4 "--> branch deleted"
1384                                                 elif [ -n "$note" ]; then
1385                                                         reportdo4 $ECHO "$note"
1386                                                         reportecho4 "--> rejected"
1387                                                 else
1388                                                         reportecho4 "--> postponed"
1389                                                 fi
1390                                         fi
1391                                 fi
1392                                 reportecho ""
1393                         done
1394                         reportecho ""
1395                 done
1396                 rm -f "$t"
1397                 $ECHO "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1398                 ;;
1399         clean)
1400                 "$SELF" fix_config
1401                 "$SELF" update -N
1402                 force=false
1403                 gotoupstream=false
1404                 fetchupstream=false
1405                 gotomaster=false
1406                 rmuntracked=false
1407                 killbranches=false
1408                 # usage:
1409                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1410                 #   ./all clean --reclone
1411                 found=false
1412                 for X in "$@"; do
1413                         if [ x"$X" = x"--reclone" ]; then
1414                                 force=true
1415                                 fetchupstream=true
1416                                 gotoupstream=true
1417                                 gotomaster=true
1418                                 rmuntracked=true
1419                                 killbranches=true
1420                         elif [ x"$X" = x"-f" ]; then
1421                                 force=true
1422                         elif [ x"$X" = x"-u" ]; then
1423                                 gotoupstream=true
1424                         elif [ x"$X" = x"-U" ]; then
1425                                 gotoupstream=true
1426                                 fetchupstream=true
1427                         elif [ x"$X" = x"-fu" ]; then
1428                                 force=true
1429                                 gotoupstream=true
1430                         elif [ x"$X" = x"-fU" ]; then
1431                                 force=true
1432                                 gotoupstream=true
1433                                 fetchupstream=true
1434                         elif [ x"$X" = x"-m" ]; then
1435                                 gotomaster=true
1436                         elif [ x"$X" = x"-r" ]; then
1437                                 rmuntracked=true
1438                         elif [ x"$X" = x"-D" ]; then
1439                                 killbranches=true
1440                         elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
1441                                 msg ''
1442                                 msg "        _____"
1443                                 msg "    ,--'-\\P/\`\\  FFFFFFF"
1444                                 msg " __/_    B/,-.\\  FFFFFFF"
1445                                 msg " /  _\\  (//  O\\\\  FFFFFF"
1446                                 msg "| (O  \`) _\\._ _)\\  FFFUU"
1447                                 msg "| |___/.^d0~~\"\\  \\ UUUU"
1448                                 msg "|     |\`~'     \\ |  UUUU"
1449                                 msg "|     |    __,C>|| UUUU"
1450                                 msg "\\    /_ ,-/,-'   |  UUUU"
1451                                 msg " \\\\_ \\_>~'      /  UUUU-"
1452                                 msg ''
1453                         else
1454                                 msg "Unknown arg: $X"
1455                         fi
1456                         found=true
1457                 done
1458                 if ! $found; then
1459                         rmuntracked=true
1460                 fi
1461                 for d in $repos; do
1462                         verbose cd "$d0/$d"
1463                         if $gotoupstream; then
1464                                 if ! $force; then
1465                                         msg "Must also use -f (delete local changes) when using -u"
1466                                         exit 1
1467                                 fi
1468                                 if $gotomaster; then
1469                                         if $fetchupstream; then
1470                                                 verbose git fetch origin
1471                                                 verbose git remote prune origin
1472                                         fi
1473                                         verbose git checkout -f "`repobranch "$d"`"
1474                                         verbose git reset --hard origin/"`repobranch "$d"`"
1475                                 else
1476                                         r=`git symbolic-ref HEAD`
1477                                         r=${r#refs/heads/}
1478                                         rem=`git config "branch.$r.remote" || $ECHO origin`
1479                                         bra=`git config "branch.$r.merge" || $ECHO "$r"`
1480                                         upstream="$rem/${bra#refs/heads/}"
1481                                         if $fetchupstream; then
1482                                                 verbose git fetch "$rem"
1483                                                 verbose git remote prune "$rem"
1484                                         fi
1485                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1486                                                 upstream="origin/`repobranch "$d"`"
1487                                         fi
1488                                         verbose git reset --hard "$upstream"
1489                                 fi
1490                         elif $gotomaster; then
1491                                 if $force; then
1492                                         verbose git checkout -f "`repobranch "$d"`"
1493                                         verbose git reset --hard
1494                                 else
1495                                         verbose git checkout "`repobranch "$d"`"
1496                                 fi
1497                         elif $force; then
1498                                 verbose git reset --hard
1499                         fi
1500                         if $rmuntracked; then
1501                                 case "$d" in
1502                                         .)
1503                                                 verbose git clean -df || true
1504                                                 ;;
1505                                         *)
1506                                                 verbose git clean -xdf || true
1507                                                 ;;
1508                                 esac
1509                         fi
1510                         if $killbranches; then
1511                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1512                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1513                                                 verbose git branch -D "${B#refs/heads/}"
1514                                         fi
1515                                 done
1516                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
1517                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch --track "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1518                         fi
1519                         checkself "$cmd" "$@"
1520                 done
1521                 ;;
1522
1523         # release building goes here
1524         release-prepare)
1525                 #"$SELF" each git clean -fxd
1526                 case "$RELEASETYPE" in
1527                         '')
1528                                 $ECHO >&2 -n "$ESC[2J$ESC[H"
1529                                 msg ""
1530                                 msg ""
1531                                 msg ""
1532                                 msg ""
1533                                 msg ""
1534                                 msg ""
1535                                 msg "        +---------------------------------------------------------.---+"
1536                                 msg "        | NOTE                                                    | X |"
1537                                 msg "        +---------------------------------------------------------^---+"
1538                                 msg "        |   ____                                                      |"
1539                                 msg "        |  /    \  This is the official release build system.         |"
1540                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1541                                 msg "        | | STOP | you are not supposed to use this script and should |"
1542                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1543                                 msg "        |  \____/  and game code.                                     |"
1544                                 msg "        |                                                             |"
1545                                 msg "        |                      [ I understand ]                       |"
1546                                 msg "        +-------------------------------------------------------------+"
1547                                 sleep 10
1548                                 # A LOT of build infrastructure is required:
1549                                 # - vorbis-tools
1550                                 # - ImageMagick
1551                                 # - .ssh/config must be configured so the following
1552                                 #   host names are reachable and have a compile
1553                                 #   infrastructure set up:
1554                                 #   - xonotic-build-linux32 (with gcc on x86)
1555                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1556                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1557                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1558                                 #     and x86_64-w64-mingw32-g++)
1559                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1560                                 # - AMD Compressonator installed in WINE
1561                                 # - ResEdit installed in WINE
1562                                 # - a lot of other requirements you will figure out
1563                                 #   while reading the error messages
1564                                 # - environment variable RELEASETYPE set
1565                                 # - optionally, environment variable RELEASEDATE set
1566                                 #   (YYYYMMDD)
1567                                 exit 1
1568                                 ;;
1569                         release)
1570                                 msg "Building a FINISHED RELEASE"
1571                                 ;;
1572                         *)
1573                                 msg "Building a $RELEASETYPE"
1574                                 ;;
1575                 esac
1576                 verbose rm -rf Xonotic Xonotic*.zip
1577                 verbose mkdir -p Xonotic
1578                 if [ -n "$RELEASEDATE" ]; then
1579                         verbose $ECHO "$RELEASEDATE" > Xonotic/stamp.txt
1580                 else
1581                         verbose date +%Y%m%d > Xonotic/stamp.txt
1582                 fi
1583                 verbose git archive --format=tar HEAD -- Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk | {
1584                         verbose cd Xonotic
1585                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc source/d0_blind_id mapping
1586                         verbose tar xvf -
1587                         verbose rm -rf misc/builddeps
1588                         verbose mv misc/buildfiles/win32/* . || true
1589                         verbose mv misc/buildfiles/win64 bin64 || true
1590                         verbose mv misc/buildfiles/osx/* . || true
1591                         verbose rm -rf misc/buildfiles
1592                         verbose rm -rf misc/pki
1593                 }
1594                 {
1595                         verbose cd darkplaces
1596                         verbose git archive --format=tar HEAD
1597                 } | {
1598                         verbose cd Xonotic/source/darkplaces
1599                         verbose tar xvf -
1600                 }
1601                 {
1602                         verbose cd fteqcc
1603                         verbose git archive --format=tar HEAD
1604                 } | {
1605                         verbose cd Xonotic/source/fteqcc
1606                         verbose tar xvf -
1607                 }
1608                 {
1609                         verbose cd data/xonotic-data.pk3dir
1610                         verbose git archive --format=tar HEAD -- qcsrc Makefile
1611                 } | {
1612                         verbose cd Xonotic/source
1613                         verbose tar xvf -
1614                 }
1615                 {
1616                         verbose cd d0_blind_id
1617                         verbose git archive --format=tar HEAD
1618                 } | {
1619                         verbose cd Xonotic/source/d0_blind_id
1620                         verbose tar xvf -
1621                         verbose sh autogen.sh
1622                 }
1623                 rm -f Xonotic/key_15.d0pk
1624                 {
1625                         verbose cd Xonotic/mapping
1626                         verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20110223.tar.bz2
1627                         verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20110223-win32-7z.exe
1628                         for X in *-7z.exe; do
1629                                 7za x "$X"
1630                                 rm -f "$X"
1631                         done
1632                         # TODO possibly include other tools?
1633                 }
1634                 ;;
1635         release-compile-run)
1636                 host=$1
1637                 buildpath=$2
1638                 maketargets=$3
1639                 makeflags=$4
1640                 srcdir=$5
1641                 depsdir=$6
1642                 targetfiles=$7
1643                 set -x
1644                 if [ -n "$targetfiles" ]; then
1645                         case " $HOSTS_THAT_ARE_DISABLED " in
1646                                 *\ $host\ *)
1647                                         exit
1648                                         ;;
1649                         esac
1650                         case " $HOSTS_THAT_ARE_MYSELF " in
1651                                 *\ $host\ *)
1652                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1653                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1654                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1655                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1656                                         for f in $targetfiles; do
1657                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1658                                         done
1659                                         ;;
1660                                 *)
1661                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1662                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1663                                         verbose ssh "$host" "[ -f /etc/profile ] && . /etc/profile; [ -f ~/.profile ] && . ~/.profile; export LC_ALL=C; ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
1664                                         for f in $targetfiles; do
1665                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1666                                         done
1667                                         ;;
1668                         esac
1669                         # now rebrand the binaries...
1670                         for f in $targetfiles; do
1671                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1672                                 case "${f##*:}" in
1673                                         Xonotic/xonotic*.exe)
1674                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1675                                                 ;;
1676                                 esac
1677                         done
1678                 fi
1679                 ;;
1680         release-compile)
1681                 suffix=$1
1682                 makeflags=$2
1683                 fteqcc_maketargets=$3
1684                 fteqcc_files=$4
1685                 darkplaces_maketargets=$5
1686                 darkplaces_files=$6
1687                 host=xonotic-build-$suffix
1688                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1689                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1690                 ;;
1691         release-engine-win32)
1692                 verbose "$SELF" release-compile win32 \
1693                         'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-gcc -march=i686 -g1 -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DUSE_WSPIAPI_H -DSUPPORTIPV6" WINDRES="i586-mingw32msvc-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN32RELEASE=1 D3D=0' \
1694                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1695                         '' ''
1696                 verbose "$SELF" release-compile win32 \
1697                         'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-g++ -g1 -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DUSE_WSPIAPI_H -DSUPPORTIPV6" WINDRES="i586-mingw32msvc-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN32RELEASE=1 D3D=1' \
1698                         '' '' \
1699                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1700                 ;;
1701         release-engine-win64)
1702                 verbose "$SELF" release-compile win64 \
1703                         'STRIP=: DP_MAKE_TARGET=mingw CC="amd64-mingw32msvc-gcc -g1 -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DSUPPORTIPV6" WINDRES="amd64-mingw32msvc-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN64RELEASE=1 D3D=0' \
1704                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1705                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1706                 verbose "$SELF" release-compile win64 \
1707                         'STRIP=: DP_MAKE_TARGET=mingw CC="x86_64-w64-mingw32-g++ -g1 -Wl,--dynamicbase -Wl,--nxcompat -I.deps/include -L.deps/lib -DSUPPORTIPV6" WINDRES="x86_64-w64-mingw32-windres" SDL_CONFIG=".deps/bin/sdl-config" LIB_JPEG= CFLAGS_LIBJPEG= WIN64RELEASE=1 D3D=1' \
1708                         '' '' \
1709                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1710                 ;;
1711         release-engine-osx)
1712                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1713                 verbose "$SELF" release-compile osx \
1714                         'STRIP=: CC="gcc -g1 -arch i386 -arch ppc -arch x86_64 -isysroot /Developer/SDKs/MacOSX10.5.sdk -mmacosx-version-min=10.4 -I.deps/include -L.deps/lib -fno-reorder-blocks -DSUPPORTIPV6"' \
1715                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1716                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1717                 ;;
1718         release-engine-linux32)
1719                 verbose "$SELF" release-compile linux32 \
1720                         'STRIP=: CC="gcc -m32 -march=i686 -g1 -I.deps/include -L.deps/lib -DSUPPORTIPV6" DP_MODPLUG_STATIC_LIBDIR=.deps/lib LIB_JPEG=.deps/lib/libjpeg.a DP_CRYPTO_STATIC_LIBDIR=.deps/lib' \
1721                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1722                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1723                 ;;
1724         release-engine-linux64)
1725                 verbose "$SELF" release-compile linux64 \
1726                         'STRIP=: CC="gcc -m64 -g1 -I.deps/include -L.deps/lib -DSUPPORTIPV6" DP_MODPLUG_STATIC_LIBDIR=.deps/lib LIB_JPEG=.deps/lib/libjpeg.a DP_CRYPTO_STATIC_LIBDIR=.deps/lib' \
1727                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1728                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1729                 ;;
1730         release-engine)
1731                 verbose "$SELF" release-engine-linux32 &
1732                 verbose "$SELF" release-engine-linux64 &
1733                 verbose "$SELF" release-engine-win32 &
1734                 verbose "$SELF" release-engine-win64 &
1735                 verbose "$SELF" release-engine-osx &
1736                 wait %1
1737                 wait %2
1738                 wait %3
1739                 wait %4
1740                 wait %5
1741                 wait
1742                 ;;
1743         release-maps)
1744                 verbose "$SELF" update-maps
1745                 ;;
1746         release-qc)
1747                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1748                 verbose rm -f Xonotic/source/qcsrc/*/fteqcc.log
1749                 ;;
1750         release-buildpk3-transform-raw)
1751                 dir=$1
1752                 ;;
1753         release-buildpk3-transform-normal)
1754                 dir=$1
1755                 verbose cd "$dir"
1756                 # texture: convert to jpeg and dds
1757                 verbose export do_jpeg=true
1758                 verbose export jpeg_qual_rgb=97
1759                 verbose export jpeg_qual_a=99
1760                 verbose export do_dds=false
1761                 verbose export do_ogg=false
1762                 verbose export del_src=true
1763                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1764                 ;;
1765         release-buildpk3-transform-normaldds)
1766                 dir=$1
1767                 verbose cd "$dir"
1768                 # texture: convert to jpeg and dds
1769                 # music: reduce bitrate
1770                 verbose export do_jpeg=false
1771                 verbose export do_jpeg_if_not_dds=true
1772                 verbose export jpeg_qual_rgb=95
1773                 verbose export jpeg_qual_a=99
1774                 verbose export do_dds=true
1775                 verbose export dds_flags=
1776                 verbose export do_ogg=true
1777                 verbose export del_src=true
1778                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1779                 ;;
1780         release-buildpk3-transform-low)
1781                 dir=$1
1782                 verbose cd "$dir"
1783                 # texture: convert to jpeg and dds
1784                 # music: reduce bitrate
1785                 verbose export do_jpeg=true
1786                 verbose export jpeg_qual_rgb=80
1787                 verbose export jpeg_qual_a=97
1788                 verbose export do_dds=false
1789                 verbose export do_ogg=true
1790                 verbose export ogg_qual=1
1791                 verbose export del_src=true
1792                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1793                 ;;
1794         release-buildpk3-transform-lowdds)
1795                 dir=$1
1796                 verbose cd "$dir"
1797                 # texture: convert to jpeg and dds
1798                 # music: reduce bitrate
1799                 verbose export do_jpeg=false
1800                 verbose export do_jpeg_if_not_dds=true
1801                 verbose export jpeg_qual_rgb=80
1802                 verbose export jpeg_qual_a=99
1803                 verbose export do_dds=true
1804                 verbose export dds_flags=
1805                 verbose export do_ogg=true
1806                 verbose export ogg_qual=1
1807                 verbose export del_src=true
1808                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1809                 ;;
1810         release-buildpk3)
1811                 src=$1
1812                 dst=$2
1813                 transform=$3
1814                 case "$dst" in
1815                         /*)
1816                                 ;;
1817                         */)
1818                                 dst="$PWD/$dst"
1819                                 ;;
1820                 esac
1821                 release_timereport
1822                 verbose rm -rf Xonotic/temp
1823                 release_timereport "deleted temp directory"
1824                 verbose mkdir -p Xonotic/temp
1825                 {
1826                         verbose cd "$src"
1827                         verbose git archive --format=tar HEAD
1828                 } | {
1829                         verbose cd Xonotic/temp
1830                         verbose tar xvf -
1831                 }
1832                 release_timereport "extracted data"
1833                 verbose cd Xonotic/temp
1834                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1835                         verbose cp ../source/progs.dat .
1836                         verbose cp ../source/csprogs.dat .
1837                         verbose cp ../source/menu.dat .
1838                         verbose rm -rf qcsrc
1839                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1840                         major=$(($gv / 10000))
1841                         minor=$((($gv / 100) - ($major * 100)))
1842                         patch=$(($gv - ($major * 10000) - ($minor * 100)))
1843                         versionstr="$major.$minor.$patch"
1844                         case "$RELEASETYPE" in
1845                                 release)
1846                                         ;;
1847                                 *)
1848                                         versionstr="$versionstr$RELEASETYPE"
1849                                         ;;
1850                         esac
1851                         verbose sed -i "
1852                                 s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1853                                 s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1854                                 s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1855                         " defaultXonotic.cfg
1856                         case "$RELEASETYPE" in
1857                                 release)
1858                                         echo "" >> defaultXonotic.cfg
1859                                         echo "// nicer menu" >> defaultXonotic.cfg
1860                                         echo "set menu_watermark \"\"" >> defaultXonotic.cfg
1861                                         ;;
1862                         esac
1863                         (
1864                                 verbose cd gfx/menu/luminos
1865                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1866                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1867                                 verbose rm background_l2.svg
1868                         )
1869                 fi
1870                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1871                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1872                                 if [ -f "$X" ]; then
1873                                         verbose unzip "$X"
1874                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1875                                 fi
1876                         done
1877                 fi
1878                 verbose export git_src_repo="$d0/$src" # skip hash-object
1879                 release_timereport "processed data"
1880                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1881                 release_timereport "transformed data"
1882                 verbose mkzipr "../../$dst" *
1883                 release_timereport "zipped data"
1884                 verbose cd ../..
1885                 verbose rm -rf Xonotic/temp
1886                 release_timereport "deleted temp directory again"
1887                 ;;
1888         release-buildpk3s)
1889                 stamp=`cat Xonotic/stamp.txt`
1890                 src=$1
1891                 shift
1892                 dst=${src%.pk3dir}
1893                 case "$dst" in
1894                         data/xonotic-*)
1895                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1896                                 ;;
1897                         *)
1898                                 dst="$dst-$stamp"
1899                                 ;;
1900                 esac
1901                 while [ "$#" -gt 1 ]; do
1902                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1903                         shift
1904                         shift
1905                 done
1906                 ;;
1907         release-pack)
1908                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir                  raw ''
1909                 verbose "$SELF" release-buildpk3s data/font-xolonium.pk3dir                     raw ''
1910                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal '-high'        low '-low' normaldds ''
1911                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal '-high'        low '-low' normaldds ''
1912                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                     raw '' low '-low'
1913                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir  normal '-high'                   normaldds ''
1914                 ;;
1915         release-pack-needsx11)
1916                 case "$DISPLAY" in
1917                         '')
1918                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1919                                 ;;
1920                         *)
1921                                 verbose "$SELF" release-pack
1922                                 ;;
1923                 esac
1924                 ;;
1925         release-zip)
1926                 stamp=`cat Xonotic/stamp.txt`
1927                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1928                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1929                 # let's pass crypto import laws of some nasty countries
1930                 crypto_libs=`find Xonotic -name \*d0_rijndael\*.so -o -name \*d0_rijndael\*.dylib -o -name \*d0_rijndael\*.dll -o -name \*d0_rijndael\*.c`
1931                 if [ -n "$crypto_libs" ]; then
1932                         verbose mkzip Xonotic-$stamp-crypto.zip \
1933                                 $crypto_libs
1934                         rm -f $crypto_libs
1935                 fi
1936                 # build the archives
1937                 verbose mkzip Xonotic-$stamp-engine.zip \
1938                         Xonotic/*.dll \
1939                         Xonotic/bin64/*.dll \
1940                         Xonotic/*.app \
1941                         Xonotic/xonotic-* \
1942                         Xonotic/xonotic.exe \
1943                         Xonotic/source/darkplaces/
1944                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1945                 verbose mkzip Xonotic-$stamp-common.zip \
1946                         Xonotic/source/fteqcc/ \
1947                         Xonotic/source/qcsrc/ \
1948                         Xonotic/Docs \
1949                         Xonotic/misc \
1950                         Xonotic/fteqcc \
1951                         Xonotic/server \
1952                         Xonotic/key_0.d0pk \
1953                         Xonotic/data/font-nimbussansl-$stamp.pk3 \
1954                         Xonotic/data/font-xolonium-$stamp.pk3
1955                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1956                 verbose mkzip0 Xonotic-$stamp.zip \
1957                         Xonotic/data/xonotic-$stamp-data.pk3 \
1958                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1959                         Xonotic/data/xonotic-$stamp-music.pk3 \
1960                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1961                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1962                 verbose mkzip0 Xonotic-$stamp-low.zip \
1963                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1964                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1965                         Xonotic/data/xonotic-$stamp-music-low.pk3
1966                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1967                 verbose mkzip0 Xonotic-$stamp-high.zip \
1968                         Xonotic/data/xonotic-$stamp-data-high.pk3 \
1969                         Xonotic/data/xonotic-$stamp-maps-high.pk3 \
1970                         Xonotic/data/xonotic-$stamp-music.pk3 \
1971                         Xonotic/data/xonotic-$stamp-nexcompat-high.pk3
1972                 verbose mkzip Xonotic-$stamp-mappingsupport.zip \
1973                         Xonotic/mapping
1974                 verbose mkzip0 Xonotic-$stamp-mappingsupport.zip \
1975                         Xonotic/data/xonotic-$stamp-maps-low.pk3 # TODO add a Radiant build
1976                 ;;
1977         release)
1978                 verbose "$SELF" release-prepare
1979                 verbose "$SELF" release-maps
1980                 verbose "$SELF" release-engine
1981                 verbose "$SELF" release-qc
1982                 verbose "$SELF" release-pack-needsx11
1983                 verbose "$SELF" release-zip
1984                 ;;
1985
1986         *)
1987                 $ECHO "Usage:"
1988                 $ECHO "  $SELF admin-merge [<branch>]"
1989                 $ECHO "  $SELF branch <branch>"
1990                 $ECHO "  $SELF branch <remote> <branch> [<srcbranch>]"
1991                 $ECHO "  $SELF branches"
1992                 $ECHO "  $SELF checkout|switch <branch>"
1993                 $ECHO "  $SELF checkout|switch <remote>/<branch>"
1994                 $ECHO "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
1995                 $ECHO "  $SELF clean --reclone"
1996                 $ECHO "  $SELF compile [-c] [-r|-p] [-0]"
1997                 $ECHO "  $SELF each|foreach [-k] command..."
1998                 $ECHO "  $SELF fix_upstream_rebase"
1999                 $ECHO "  $SELF keygen"
2000                 $ECHO "  $SELF merge"
2001                 $ECHO "  $SELF push|commit [-s]"
2002                 $ECHO "  $SELF release"
2003                 $ECHO "  $SELF restore-patches"
2004                 $ECHO "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
2005                 $ECHO "  $SELF save-patches"
2006                 $ECHO "  $SELF update-maps"
2007                 $ECHO "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
2008                 ;;
2009 esac