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