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