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