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