don't fetch the repo in between, that would be bad
[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 -mtune=native -march=native"
804                                         shift
805                                         ;;
806                                 *)
807                                         break
808                                         ;;
809                         esac
810                 done
811                 if [ -n "$WE_HATE_OUR_USERS" ]; then
812                         TARGETS="sv-$debug cl-$debug"
813                 elif [ x"`uname`" = x"Darwin" ]; then
814                         case "`uname -r`" in
815                                 ?.*)
816                                         TARGETS="sv-$debug cl-$debug sdl-$debug"
817                                         ;;
818                                 *)
819                                         # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
820                                         snowleopardhack=true
821                                         TARGETS="sv-$debug sdl-$debug"
822                                         ;;
823                         esac
824                         export CC="$CC -I$PWD/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks/SDL.framework/Headers -F$PWD/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks"
825                 else
826                         TARGETS="sv-$debug cl-$debug sdl-$debug"
827                 fi
828                 if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
829                         # if we give the command make the arg "", it will surely fail (invalid filename),
830                         # so better handle it as an empty client option
831                         BAD_TARGETS=" "
832                         shift
833                 elif [ -n "$1" ]; then
834                         BAD_TARGETS=
835                         TARGETS_SAVE=$TARGETS
836                         TARGETS=
837                         for X in $1; do
838                                 case "$X" in
839                                         sdl)
840                                                 TARGETS="$TARGETS sdl-debug"
841                                                 ;;
842                                         agl)
843                                                 TARGETS="$TARGETS cl-debug"
844                                                 if $snowleopardhack; then
845                                                         export CC="$CC -arch i386"
846                                                 fi
847                                                 ;;
848                                         glx|wgl)
849                                                 TARGETS="$TARGETS cl-debug"
850                                                 ;;
851                                         dedicated)
852                                                 TARGETS="$TARGETS sv-debug"
853                                                 ;;
854                                         *)
855                                                 BAD_TARGETS="$BAD_TARGETS $X"
856                                                 ;;
857                                 esac
858                         done
859                         if [ -n "$TARGETS" ]; then # at least a valid client
860                                 shift
861                         else # no valid client, let's assume this option is not meant to be a client then
862                                 TARGETS=$TARGETS_SAVE
863                                 BAD_TARGETS=
864                         fi
865                 fi
866                 if [ -z "$MAKEFLAGS" ]; then
867                         if [ -f /proc/cpuinfo ]; then
868                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
869                                 if [ $ncpus -gt 1 ]; then
870                                         MAKEFLAGS=-j$ncpus
871                                 fi
872                         fi
873                         if [ -n "$WE_HATE_OUR_USERS" ]; then
874                                 MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
875                         fi
876                 fi
877
878                 enter "$d0/d0_blind_id" verbose
879                 if ! $compiled0; then
880                         # compilation of crypto library failed
881                         # use binaries then, if we can...
882                         mkdir -p .libs
883                         if [ -n "$WE_HATE_OUR_USERS" ]; then
884                                 verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
885                                 verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
886                         else
887                                 case "`uname`" in
888                                         Linux)
889                                                 case `uname -m` in
890                                                         x86_64)
891                                                                 verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
892                                                                 verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
893                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
894                                                                 ;;
895                                                         *86)
896                                                                 verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
897                                                                 verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
898                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
899                                                                 ;;
900                                                         *)
901                                                                 compiled0=true
902                                                                 ;;
903                                                 esac
904                                                 ;;
905                                         Darwin)
906                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
907                                                 ;;
908                                         *)
909                                                 compiled0=true
910                                                 ;;
911                                 esac
912                         fi
913                 fi
914                 if $compiled0; then
915                         if $cleand0; then
916                                 if [ -f Makefile ]; then
917                                         verbose make $MAKEFLAGS distclean
918                                 fi
919                         fi
920                         if ! [ -f Makefile ]; then
921                                 verbose sh autogen.sh
922                                 verbose ./configure
923                         fi
924                         verbose make $MAKEFLAGS
925                 fi
926
927                 enter "$d0/fteqcc" verbose
928                 if $cleanqcc; then
929                         verbose make $MAKEFLAGS clean
930                 fi
931                 verbose make $MAKEFLAGS
932
933                 enter "$d0/data/xonotic-data.pk3dir" verbose
934                 if $cleanqc; then
935                         verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
936                 fi
937                 verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
938                 # 4 levels up: data, xonotic-data, qcsrc, server
939
940                 enter "$d0/darkplaces" verbose
941                 if [ x"$BAD_TARGETS" = x" " ]; then
942                         $ECHO "Warning: invalid empty client, default clients will be used."
943                 fi
944                 if $cleandp; then
945                         verbose make $MAKEFLAGS clean
946                 fi
947                 for T in $TARGETS; do
948                         verbose make $MAKEFLAGS STRIP=: "$@" "$T"
949                 done
950                 for T in $BAD_TARGETS; do
951                         $ECHO "Warning: discarded invalid client $T."
952                 done
953
954                 verbose "$SELF" update-maps
955                 ;;
956         run)
957                 if [ -n "$WE_HATE_OUR_USERS" ]; then
958                         client=
959                         export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
960                 elif [ x"`uname`" = x"Darwin" ]; then
961                         export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic-SDL.app/Contents/MacOS:$d0/d0_blind_id/.libs"
962                         export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic-SDL.app/Contents/Frameworks"
963                         client=-sdl
964                 else
965                         export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
966                         client=-sdl
967                 fi
968                 case "$1" in
969                         sdl|glx|agl|dedicated)
970                                 client=-$1
971                                 shift
972                                 ;;
973                         wgl)
974                                 client=
975                                 shift
976                                 ;;
977                 esac
978                 if ! [ -x "darkplaces/darkplaces$client" ]; then
979                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
980                                 client=$client.exe
981                         else
982                                 $ECHO "Client darkplaces/darkplaces$client not found, aborting"
983                                 exit 1
984                         fi
985                 fi
986                 set -- "darkplaces/darkplaces$client" -xonotic -mygames "$@"
987
988                 # if pulseaudio is running: USE IT
989                 if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
990                         if ps -C pulseaudio >/dev/null; then
991                                 if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
992                                         export SDL_AUDIODRIVER=pulse
993                                 fi
994                         fi
995                 fi
996
997                 binary=$1
998
999                 if [ -n "$USE_GDB" ]; then
1000                         set -- gdb --args "$@"
1001                 elif which gdb >/dev/null 2>&1; then
1002                         set -- gdb --batch -x savecore.gdb --args "$@"
1003                 elif which catchsegv >/dev/null 2>&1; then
1004                         set -- catchsegv "$@"
1005                 fi
1006                 rm -f xonotic.core
1007                 "$@" || true
1008                 if [ -f xonotic.core ]; then
1009                         if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
1010                                 gdb "$binary" xonotic.core
1011                         #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
1012                         #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
1013                         #       # somehow send it
1014                         #       rm -f xonotic.core.tar.gz
1015                         else
1016                                 $ECHO "The core dump can be examined later by"
1017                                 $ECHO "  gdb $binary xonotic.core"
1018                         fi
1019                 fi
1020                 ;;
1021         each|foreach)
1022                 keep_going=false
1023                 if [ x"$1" = x"-k" ]; then
1024                         keep_going=true
1025                         shift
1026                 fi
1027                 for d in $repos; do
1028                         if verbose cd "$d0/$d"; then
1029                                 if $keep_going; then
1030                                         verbose "$@" || true
1031                                 else
1032                                         verbose "$@"
1033                                 fi
1034                                 cd "$d0"
1035                         fi
1036                 done
1037                 ;;
1038         save-patches)
1039                 outfile=$1
1040                 patchdir=`mktemp -d -t save-patches.XXXXXX`
1041                 for d in $repos; do
1042                         enter "$d0/$d" verbose
1043                         git branch -v -v | cut -c 3- | {
1044                                 i=0
1045                                 while read -r BRANCH REV UPSTREAM TEXT; do
1046                                         case "$UPSTREAM" in
1047                                                 \[*)
1048                                                         UPSTREAM=${UPSTREAM#\[}
1049                                                         UPSTREAM=${UPSTREAM%\]}
1050                                                         UPSTREAM=${UPSTREAM%:*}
1051                                                         TRACK=true
1052                                                         ;;
1053                                                 *)
1054                                                         UPSTREAM=origin/"`repobranch "$d"`"
1055                                                         TRACK=false
1056                                                         ;;
1057                                         esac
1058                                         if [ x"$REV" = x"->" ]; then
1059                                                 continue
1060                                         fi
1061                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
1062                                                 $ECHO "$d" > "$patchdir/$i/info.txt"
1063                                                 $ECHO "$BRANCH" >> "$patchdir/$i/info.txt"
1064                                                 $ECHO "$UPSTREAM" >> "$patchdir/$i/info.txt"
1065                                                 $ECHO "$TRACK" >> "$patchdir/$i/info.txt"
1066                                                 i=$(($i+1))
1067                                         else
1068                                                 rm -rf "$patchdir/$i"
1069                                         fi
1070                                 done
1071                         }
1072                 done
1073                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
1074                 rm -rf "$patchdir"
1075                 ;;
1076         restore-patches)
1077                 infile=$1
1078                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
1079                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
1080                 # detach the head
1081                 for P in "$patchdir"/*/info.txt; do
1082                         D=${P%/info.txt}
1083                         exec 3<"$P"
1084                         read -r d <&3
1085                         read -r BRANCH <&3
1086                         read -r UPSTREAM <&3
1087                         read -r TRACK <&3
1088                         verbose git checkout HEAD^0
1089                         verbose git branch -D "$BRANCH"
1090                         if [ x"$TRACK" = x"true" ]; then
1091                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
1092                         else
1093                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
1094                         fi
1095                         verbose git am "$D"
1096                 done
1097                 rm -rf "$patchdir"
1098                 ;;
1099         admin-merge)
1100                 branch=$1
1101                 t=`mktemp`
1102                 report=""
1103                 reportecho()
1104                 {
1105                         report=$report"$*$LF"
1106                         $ECHO "$*"
1107                 }
1108                 reportecho4()
1109                 {
1110                         report=$report"    $*$LF"
1111                         $ECHO "    $*"
1112                 }
1113                 reportdo4()
1114                 {
1115                         o=`"$@" | sed 's/^/    /' || true`
1116                         reportecho "$o"
1117                 }
1118                 for d in $repos; do
1119                         case "$d" in
1120                                 fteqcc)
1121                                         # sorry, fteqcc repo is managed manually
1122                                         continue
1123                                         ;;
1124                         esac
1125                         enter "$d0/$d" verbose
1126                         base="`repobranch "$d"`"
1127                         reportecho "In $d:"
1128                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
1129                                 case "${ref#refs/remotes/origin/}" in
1130                                         "$base")
1131                                                 continue
1132                                                 ;;
1133                                         HEAD|master)
1134                                                 continue
1135                                                 ;;
1136                                         */*)
1137                                                 ;;
1138                                         *)
1139                                                 continue
1140                                                 ;;
1141                                 esac
1142                                 if [ -n "$branch" ]; then
1143                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1144                                                 continue
1145                                         fi
1146                                 fi
1147                                 case "$base" in
1148                                         master)
1149                                                 realbase=$base
1150                                                 ;;
1151                                         *)
1152                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1153                                                 l1=`git rev-list master.."$ref" | wc -l`
1154                                                 if [ $l0 -gt $l1 ]; then
1155                                                         realbase=master
1156                                                 else
1157                                                         realbase=$base
1158                                                 fi
1159                                                 ;;
1160                                 esac
1161                                 reportecho "  Branch $ref:"
1162                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1163                                 logdata=`git log --color "$realbase".."$ref"`
1164                                 if [ -z "$logdata" ]; then
1165                                         reportecho4 "--> not merging, no changes vs master"
1166                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1167                                                 git push origin :"${ref#refs/remotes/origin/}"
1168                                                 reportecho4 "--> branch deleted"
1169                                         fi
1170                                 else
1171                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1172                                         if [ -z "$diffdata" ]; then
1173                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1174                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ $ECHO "$logdata"; } | less -r'; then
1175                                                         git push origin :"${ref#refs/remotes/origin/}"
1176                                                         reportecho4 "--> branch deleted"
1177                                                 fi
1178                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1179                                                 reportdo4 $ECHO "$note"
1180                                                 reportecho4 "--> not merging, already had this one rejected before"
1181                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ $ECHO "$logdata"; $ECHO "$diffdata"; } | less -r'; then
1182                                                 git checkout "$realbase"
1183                                                 org=`git rev-parse HEAD`
1184                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1185                                                         git reset --hard "$org"
1186                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1187                                                         reportdo4 cat "$t"
1188                                                         reportecho4 "--> merge failed"
1189                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1190                                                         git reset --hard "$org"
1191                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1192                                                         reportdo4 cat "$t"
1193                                                         reportecho4 "--> compile failed"
1194                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1195                                                         git reset --hard "$org"
1196                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1197                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1198                                                         if [ x"$note" = x"del" ]; then
1199                                                                 git push origin :"${ref#refs/remotes/origin/}"
1200                                                                 reportecho4 "--> test failed, branch deleted"
1201                                                         elif [ -n "$note" ]; then
1202                                                                 reportdo4 $ECHO "$note"
1203                                                                 reportecho4 "--> test failed"
1204                                                         else
1205                                                                 reportecho4 "--> test failed, postponed"
1206                                                         fi
1207                                                 else
1208                                                         # apply crlf, or other cleanup filters (non-behavioural changes)
1209                                                         git reset --hard
1210                                                         find . -type f -exec touch {} \;
1211                                                         git commit -a --amend -C HEAD || true # don't fail if nothing to commit
1212
1213                                                         $ECHO "MERGING"
1214                                                         case ",`repoflags "$d"`," in
1215                                                                 *,svn,*)
1216                                                                         # we do quite a mess here... luckily we know $org
1217                                                                         git fetch # svn needs to be current
1218                                                                         git rebase -i --onto origin/master "$org"
1219                                                                         git svn dcommit --add-author-from
1220                                                                         git reset --hard "$org"
1221                                                                         ;;
1222                                                                 *)
1223                                                                         git push origin HEAD
1224                                                                         ;;
1225                                                         esac
1226                                                         reportecho4 "--> MERGED"
1227                                                         if yesno "Delete original branch \"$ref\"?"; then
1228                                                                 git push origin :"${ref#refs/remotes/origin/}"
1229                                                                 reportecho4 "--> branch deleted"
1230                                                         fi
1231                                                 fi
1232                                         else
1233                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1234                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1235                                                 if [ x"$note" = x"del" ]; then
1236                                                         git push origin :"${ref#refs/remotes/origin/}"
1237                                                         reportecho4 "--> branch deleted"
1238                                                 elif [ -n "$note" ]; then
1239                                                         reportdo4 $ECHO "$note"
1240                                                         reportecho4 "--> rejected"
1241                                                 else
1242                                                         reportecho4 "--> postponed"
1243                                                 fi
1244                                         fi
1245                                 fi
1246                                 reportecho ""
1247                         done
1248                         reportecho ""
1249                 done
1250                 rm -f "$t"
1251                 $ECHO "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1252                 ;;
1253         clean)
1254                 "$SELF" fix_config
1255                 "$SELF" update -N
1256                 force=false
1257                 gotoupstream=false
1258                 fetchupstream=false
1259                 gotomaster=false
1260                 rmuntracked=false
1261                 killbranches=false
1262                 # usage:
1263                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1264                 #   ./all clean --reclone
1265                 found=false
1266                 for X in "$@"; do
1267                         if [ x"$X" = x"--reclone" ]; then
1268                                 force=true
1269                                 fetchupstream=true
1270                                 gotoupstream=true
1271                                 gotomaster=true
1272                                 rmuntracked=true
1273                                 killbranches=true
1274                         elif [ x"$X" = x"-f" ]; then
1275                                 force=true
1276                         elif [ x"$X" = x"-u" ]; then
1277                                 gotoupstream=true
1278                         elif [ x"$X" = x"-U" ]; then
1279                                 gotoupstream=true
1280                                 fetchupstream=true
1281                         elif [ x"$X" = x"-fu" ]; then
1282                                 force=true
1283                                 gotoupstream=true
1284                         elif [ x"$X" = x"-fU" ]; then
1285                                 force=true
1286                                 gotoupstream=true
1287                                 fetchupstream=true
1288                         elif [ x"$X" = x"-m" ]; then
1289                                 gotomaster=true
1290                         elif [ x"$X" = x"-r" ]; then
1291                                 rmuntracked=true
1292                         elif [ x"$X" = x"-D" ]; then
1293                                 killbranches=true
1294                         elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
1295                                 msg ''
1296                                 msg "        _____"
1297                                 msg "    ,--'-\\P/\`\\  FFFFFFF"
1298                                 msg " __/_    B/,-.\\  FFFFFFF"
1299                                 msg " /  _\\  (//  O\\\\  FFFFFF"
1300                                 msg "| (O  \`) _\\._ _)\\  FFFUU"
1301                                 msg "| |___/.^d0~~\"\\  \\ UUUU"
1302                                 msg "|     |\`~'     \\ |  UUUU"
1303                                 msg "|     |    __,C>|| UUUU"
1304                                 msg "\\    /_ ,-/,-'   |  UUUU"
1305                                 msg " \\\\_ \\_>~'      /  UUUU-"
1306                                 msg ''
1307                         else
1308                                 msg "Unknown arg: $X"
1309                         fi
1310                         found=true
1311                         shift
1312                 done
1313                 if ! $found; then
1314                         rmuntracked=true
1315                 fi
1316                 for d in $repos; do
1317                         verbose cd "$d0/$d"
1318                         if $gotoupstream; then
1319                                 if ! $force; then
1320                                         msg "Must also use -f (delete local changes) when using -u"
1321                                         exit 1
1322                                 fi
1323                                 if $gotomaster; then
1324                                         if $fetchupstream; then
1325                                                 verbose git fetch origin
1326                                                 verbose git remote prune origin
1327                                         fi
1328                                         verbose git checkout -f "`repobranch "$d"`"
1329                                         verbose git reset --hard origin/"`repobranch "$d"`"
1330                                 else
1331                                         r=`git symbolic-ref HEAD`
1332                                         r=${r#refs/heads/}
1333                                         rem=`git config "branch.$r.remote" || $ECHO origin`
1334                                         bra=`git config "branch.$r.merge" || $ECHO "$r"`
1335                                         upstream="$rem/${bra#refs/heads/}"
1336                                         if $fetchupstream; then
1337                                                 verbose git fetch "$rem"
1338                                                 verbose git remote prune "$rem"
1339                                         fi
1340                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1341                                                 upstream="origin/`repobranch "$d"`"
1342                                         fi
1343                                         verbose git reset --hard "$upstream"
1344                                 fi
1345                         elif $gotomaster; then
1346                                 if $force; then
1347                                         verbose git checkout -f "`repobranch "$d"`"
1348                                         verbose git reset --hard
1349                                 else
1350                                         verbose git checkout "`repobranch "$d"`"
1351                                 fi
1352                         elif $force; then
1353                                 verbose git reset --hard
1354                         fi
1355                         if $rmuntracked; then
1356                                 case "$d" in
1357                                         .)
1358                                                 verbose git clean -df
1359                                                 ;;
1360                                         *)
1361                                                 verbose git clean -xdf
1362                                                 ;;
1363                                 esac
1364                         fi
1365                         if $killbranches; then
1366                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1367                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1368                                                 verbose git branch -D "${B#refs/heads/}"
1369                                         fi
1370                                 done
1371                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch -t master origin/master || true
1372                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch -t "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1373                         fi
1374                         checkself "$cmd" "$@"
1375                 done
1376                 ;;
1377
1378         # release building goes here
1379         release-prepare)
1380                 #"$SELF" each git clean -fxd
1381                 case "$RELEASETYPE" in
1382                         beta)
1383                                 msg "Building a BETA"
1384                                 ;;
1385                         release)
1386                                 msg "Building a RELEASE"
1387                                 ;;
1388                         *)
1389                                 $ECHO >&2 -n "$ESC[2J$ESC[H"
1390                                 msg ""
1391                                 msg ""
1392                                 msg ""
1393                                 msg ""
1394                                 msg ""
1395                                 msg ""
1396                                 msg "        +---------------------------------------------------------.---+"
1397                                 msg "        | NOTE                                                    | X |"
1398                                 msg "        +---------------------------------------------------------^---+"
1399                                 msg "        |   ____                                                      |"
1400                                 msg "        |  /    \  This is the official release build system.         |"
1401                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1402                                 msg "        | | STOP | you are not supposed to use this script and should |"
1403                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1404                                 msg "        |  \____/  and game code.                                     |"
1405                                 msg "        |                                                             |"
1406                                 msg "        |                      [ I understand ]                       |"
1407                                 msg "        +-------------------------------------------------------------+"
1408                                 sleep 10
1409                                 # A LOT of build infrastructure is required:
1410                                 # - vorbis-tools
1411                                 # - ImageMagick
1412                                 # - .ssh/config must be configured so the following
1413                                 #   host names are reachable and have a compile
1414                                 #   infrastructure set up:
1415                                 #   - xonotic-build-linux32 (with gcc on x86)
1416                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1417                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1418                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1419                                 #     and x86_64-w64-mingw32-g++)
1420                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1421                                 # - AMD Compressonator installed in WINE
1422                                 # - ResEdit installed in WINE
1423                                 # - a lot of other requirements you will figure out
1424                                 #   while reading the error messages
1425                                 # - environment variable RELEASETYPE set
1426                                 # - optionally, environment variable RELEASEDATE set
1427                                 #   (YYYYMMDD)
1428                                 exit 1
1429                                 ;;
1430                 esac
1431                 verbose rm -rf Xonotic Xonotic*.zip
1432                 verbose mkdir -p Xonotic
1433                 if [ -n "$RELEASEDATE" ]; then
1434                         verbose $ECHO "$RELEASEDATE" > Xonotic/stamp.txt
1435                 else
1436                         verbose date +%Y%m%d > Xonotic/stamp.txt
1437                 fi
1438                 verbose git archive --format=tar HEAD -- Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk | {
1439                         verbose cd Xonotic
1440                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc
1441                         verbose tar xvf -
1442                         verbose rm -rf misc/builddeps
1443                         verbose mv misc/buildfiles/win32/* . || true
1444                         verbose mv misc/buildfiles/win64 bin64 || true
1445                         verbose mv misc/buildfiles/osx/* . || true
1446                         verbose rm -rf misc/buildfiles
1447                         verbose rm -rf misc/pki
1448                 }
1449                 {
1450                         verbose cd darkplaces
1451                         verbose git archive --format=tar HEAD
1452                 } | {
1453                         verbose cd Xonotic/source/darkplaces
1454                         verbose tar xvf -
1455                 }
1456                 {
1457                         verbose cd fteqcc
1458                         verbose git archive --format=tar HEAD
1459                 } | {
1460                         verbose cd Xonotic/source/fteqcc
1461                         verbose tar xvf -
1462                 }
1463                 {
1464                         verbose cd data/xonotic-data.pk3dir
1465                         verbose git archive --format=tar HEAD -- qcsrc Makefile
1466                 } | {
1467                         verbose cd Xonotic/source
1468                         verbose tar xvf -
1469                 }
1470                 rm -f Xonotic/key_15.d0pk
1471                 ;;
1472         release-compile-run)
1473                 host=$1
1474                 buildpath=$2
1475                 maketargets=$3
1476                 makeflags=$4
1477                 srcdir=$5
1478                 depsdir=$6
1479                 targetfiles=$7
1480                 set -x
1481                 if [ -n "$targetfiles" ]; then
1482                         case " $HOSTS_THAT_ARE_DISABLED " in
1483                                 *\ $host\ *)
1484                                         exit
1485                                         ;;
1486                         esac
1487                         case " $HOSTS_THAT_ARE_MYSELF " in
1488                                 *\ $host\ *)
1489                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1490                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1491                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1492                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1493                                         for f in $targetfiles; do
1494                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1495                                         done
1496                                         ;;
1497                                 *)
1498                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1499                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1500                                         verbose ssh "$host" "ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
1501                                         for f in $targetfiles; do
1502                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1503                                         done
1504                                         ;;
1505                         esac
1506                         # now rebrand the binaries...
1507                         for f in $targetfiles; do
1508                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1509                                 case "${f##*:}" in
1510                                         xonotic*.exe)
1511                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1512                                                 (
1513                                                         d=`mktemp -d -t rebrand.XXXXXX`
1514                                                         cd "$d"
1515                                                         $ECHO "-mygames" > darkplaces.opt
1516                                                         zip -9r darkplaces.zip darkplaces.opt
1517                                                         cat darkplaces.zip
1518                                                         cd "$d0"
1519                                                         rm -rf "$d"
1520                                                 ) >> "${f##*:}"
1521                                                 ;;
1522                                 esac
1523                         done
1524                 fi
1525                 ;;
1526         release-compile)
1527                 suffix=$1
1528                 makeflags=$2
1529                 fteqcc_maketargets=$3
1530                 fteqcc_files=$4
1531                 darkplaces_maketargets=$5
1532                 darkplaces_files=$6
1533                 host=xonotic-build-$suffix
1534                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1535                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1536                 ;;
1537         release-engine-win32)
1538                 verbose "$SELF" release-compile win32 \
1539                         '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' \
1540                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1541                         '' ''
1542                 verbose "$SELF" release-compile win32 \
1543                         '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' \
1544                         '' '' \
1545                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1546                 ;;
1547         release-engine-win64)
1548                 verbose "$SELF" release-compile win64 \
1549                         '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' \
1550                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1551                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1552                 verbose "$SELF" release-compile win64 \
1553                         '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' \
1554                         '' '' \
1555                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1556                 ;;
1557         release-engine-osx)
1558                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1559                 verbose "$SELF" release-compile osx \
1560                         '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"' \
1561                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1562                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic-SDL.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1563                 verbose "$SELF" release-compile osx \
1564                         '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"' \
1565                         '' '' \
1566                         'cl-release' 'darkplaces-agl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-agl-bin'
1567                 ;;
1568         release-engine-linux32)
1569                 verbose "$SELF" release-compile linux32 \
1570                         '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' \
1571                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1572                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1573                 ;;
1574         release-engine-linux64)
1575                 verbose "$SELF" release-compile linux64 \
1576                         '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' \
1577                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1578                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1579                 ;;
1580         release-engine)
1581                 verbose "$SELF" release-engine-linux32 &
1582                 verbose "$SELF" release-engine-linux64 &
1583                 verbose "$SELF" release-engine-win32 &
1584                 verbose "$SELF" release-engine-win64 &
1585                 verbose "$SELF" release-engine-osx &
1586                 wait %1
1587                 wait %2
1588                 wait %3
1589                 wait %4
1590                 wait %5
1591                 wait
1592                 ;;
1593         release-maps)
1594                 verbose "$SELF" update-maps
1595                 ;;
1596         release-qc)
1597                 case "$RELEASETYPE" in
1598                         beta)
1599                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1600                                 # back out of: source/qcsrc/server
1601                                 ;;
1602                         release)
1603                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 FTEQCCFLAGS_WATERMARK= clean all
1604                                 ;;
1605                 esac
1606                 verbose rm -f Xonotic/source/*/fteqcc.log
1607                 ;;
1608         release-buildpk3-transform-raw)
1609                 dir=$1
1610                 ;;
1611         release-buildpk3-transform-normal)
1612                 dir=$1
1613                 verbose cd "$dir"
1614                 # texture: convert to jpeg and dds
1615                 verbose export do_jpeg=true
1616                 verbose export jpeg_qual_rgb=95
1617                 verbose export jpeg_qual_a=99
1618                 verbose export do_dds=true
1619                 verbose export dds_flags=
1620                 verbose export do_ogg=false
1621                 verbose export del_src=true
1622                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1623                 ;;
1624         release-buildpk3-transform-low)
1625                 dir=$1
1626                 verbose cd "$dir"
1627                 # texture: convert to jpeg and dds
1628                 # music: reduce bitrate
1629                 verbose export do_jpeg=true
1630                 verbose export jpeg_qual_rgb=80
1631                 verbose export jpeg_qual_a=97
1632                 verbose export do_dds=false
1633                 verbose export do_ogg=true
1634                 verbose export ogg_qual=1
1635                 verbose export del_src=true
1636                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1637                 ;;
1638         release-buildpk3-transform-lowdds)
1639                 dir=$1
1640                 verbose cd "$dir"
1641                 # texture: convert to jpeg and dds
1642                 # music: reduce bitrate
1643                 verbose export do_jpeg=false
1644                 verbose export do_jpeg_if_not_dds=true
1645                 verbose export jpeg_qual_rgb=80
1646                 verbose export jpeg_qual_a=99
1647                 verbose export do_dds=true
1648                 verbose export dds_flags=
1649                 verbose export do_ogg=true
1650                 verbose export ogg_qual=1
1651                 verbose export del_src=true
1652                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1653                 ;;
1654         release-buildpk3)
1655                 src=$1
1656                 dst=$2
1657                 transform=$3
1658                 case "$dst" in
1659                         /*)
1660                                 ;;
1661                         */)
1662                                 dst="$PWD/$dst"
1663                                 ;;
1664                 esac
1665                 verbose rm -rf Xonotic/temp
1666                 verbose mkdir -p Xonotic/temp
1667                 {
1668                         verbose cd "$src"
1669                         verbose git archive --format=tar HEAD
1670                 } | {
1671                         verbose cd Xonotic/temp
1672                         verbose tar xvf -
1673                 }
1674                 verbose cd Xonotic/temp
1675                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1676                         verbose cp ../source/progs.dat .
1677                         verbose cp ../source/csprogs.dat .
1678                         verbose cp ../source/menu.dat .
1679                         verbose rm -rf qcsrc
1680                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1681                         major=$(($gv / 10000))
1682                         minor=$(($gv / 100 - $major * 100))
1683                         patch=$(($gv - $major * 10000 - $minor * 100))
1684                         versionstr="$major.$minor.$patch"
1685                         case "$RELEASETYPE" in
1686                                 beta)
1687                                         versionstr="$versionstr""beta"
1688                                         ;;
1689                         esac
1690                         verbose sed -i "
1691                                 s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1692                                 s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1693                                 s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1694                         " defaultXonotic.cfg
1695                         (
1696                                 verbose cd gfx/menu/luminos
1697                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1698                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1699                                 verbose rm background_l2.svg
1700                         )
1701                 fi
1702                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1703                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1704                                 if [ -f "$X" ]; then
1705                                         verbose unzip "$X"
1706                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1707                                 fi
1708                         done
1709                 fi
1710                 verbose export git_src_repo="$d0/$src" # skip hash-object
1711                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1712                 verbose mkzip "../../$dst" *
1713                 verbose cd ../..
1714                 verbose rm -rf Xonotic/temp
1715                 ;;
1716         release-buildpk3s)
1717                 stamp=`cat Xonotic/stamp.txt`
1718                 src=$1
1719                 shift
1720                 dst=${src%.pk3dir}
1721                 case "$dst" in
1722                         data/xonotic-*)
1723                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1724                                 ;;
1725                         *)
1726                                 dst="$dst-$stamp"
1727                                 ;;
1728                 esac
1729                 while [ "$#" -gt 1 ]; do
1730                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1731                         shift
1732                         shift
1733                 done
1734                 ;;
1735         release-pack)
1736                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir             raw ''
1737                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1738                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1739                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                raw ''     low '-low'
1740                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir                       low ''
1741                 ;;
1742         release-pack-needsx11)
1743                 case "$DISPLAY" in
1744                         '')
1745                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1746                                 ;;
1747                         *)
1748                                 verbose "$SELF" release-pack
1749                                 ;;
1750                 esac
1751                 ;;
1752         release-zip)
1753                 stamp=`cat Xonotic/stamp.txt`
1754                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1755                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1756                 # let's pass crypto import laws of some nasty countries
1757                 crypto_libs=`find Xonotic -name \*d0_rijndael\*`
1758                 if [ -n "$crypto_libs" ]; then
1759                         verbose mkzip Xonotic-$stamp-crypto.zip \
1760                                 $crypto_libs
1761                         rm -f $crypto_libs
1762                 fi
1763                 # build the archives
1764                 verbose mkzip Xonotic-$stamp-engine.zip \
1765                         Xonotic/*.dll \
1766                         Xonotic/bin64/*.dll \
1767                         Xonotic/*.app \
1768                         Xonotic/xonotic-* \
1769                         Xonotic/xonotic.exe \
1770                         Xonotic/source/darkplaces/
1771                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1772                 verbose mkzip Xonotic-$stamp-common.zip \
1773                         Xonotic/source/fteqcc/ \
1774                         Xonotic/source/qcsrc/ \
1775                         Xonotic/Docs \
1776                         Xonotic/misc \
1777                         Xonotic/fteqcc \
1778                         Xonotic/server \
1779                         Xonotic/key_0.d0pk \
1780                         Xonotic/data/font-nimbussansl-$stamp.pk3
1781                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1782                 verbose mkzip0 Xonotic-$stamp.zip \
1783                         Xonotic/data/xonotic-$stamp-data.pk3 \
1784                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1785                         Xonotic/data/xonotic-$stamp-music.pk3 \
1786                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1787                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1788                 verbose mkzip0 Xonotic-$stamp-low.zip \
1789                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1790                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1791                         Xonotic/data/xonotic-$stamp-music-low.pk3
1792 #               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1793 #               verbose mkzip0 Xonotic-$stamp-high.zip \
1794 #                       Xonotic/data/xonotic-$stamp-data-raw.pk3 \
1795 #                       Xonotic/data/xonotic-$stamp-maps-raw.pk3 \
1796 #                       Xonotic/data/xonotic-$stamp-music.pk3 \
1797 #                       Xonotic/data/xonotic-$stamp-nexcompat.pk3
1798                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-lowdds.zip
1799                 verbose mkzip0 Xonotic-$stamp-lowdds.zip \
1800                         Xonotic/data/xonotic-$stamp-data-lowdds.pk3 \
1801                         Xonotic/data/xonotic-$stamp-maps-lowdds.pk3 \
1802                         Xonotic/data/xonotic-$stamp-music-low.pk3
1803                 ;;
1804         release)
1805                 verbose "$SELF" release-prepare
1806                 verbose "$SELF" release-maps
1807                 verbose "$SELF" release-engine
1808                 verbose "$SELF" release-qc
1809                 verbose "$SELF" release-pack-needsx11
1810                 verbose "$SELF" release-zip
1811                 ;;
1812
1813         *)
1814                 $ECHO "Usage:"
1815                 $ECHO "  $SELF admin-merge [<branch>]"
1816                 $ECHO "  $SELF branch <branch>"
1817                 $ECHO "  $SELF branch <remote> <branch> [<srcbranch>]"
1818                 $ECHO "  $SELF branches"
1819                 $ECHO "  $SELF checkout|switch <branch>"
1820                 $ECHO "  $SELF checkout|switch <remote>/<branch>"
1821                 $ECHO "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
1822                 $ECHO "  $SELF clean --reclone"
1823                 $ECHO "  $SELF compile [-c] [-r] [-0]"
1824                 $ECHO "  $SELF each|foreach [-k] command..."
1825                 $ECHO "  $SELF fix_upstream_rebase"
1826                 $ECHO "  $SELF keygen"
1827                 $ECHO "  $SELF merge"
1828                 $ECHO "  $SELF push|commit [-s]"
1829                 $ECHO "  $SELF release"
1830                 $ECHO "  $SELF restore-patches"
1831                 $ECHO "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
1832                 $ECHO "  $SELF save-patches"
1833                 $ECHO "  $SELF update-maps"
1834                 $ECHO "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
1835                 ;;
1836 esac