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