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