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