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