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