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