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