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