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