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