]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
fix another error case
[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                                                         export CC="$CC -mtune=native -march=native"
967                                                         ;;
968                                         esac
969                                         if [ -n "$WE_HATE_OUR_USERS" ]; then
970                                                 export CC="$CC -fno-common"
971                                         fi
972                                         shift
973                                         ;;
974                                 *)
975                                         break
976                                         ;;
977                         esac
978                 done
979                 if [ -n "$WE_HATE_OUR_USERS" ]; then
980                         TARGETS="sv-$debug cl-$debug"
981                 elif [ x"`uname`" = x"Darwin" ]; then
982                         case "`uname -r`" in
983                                 ?.*)
984                                         TARGETS="sv-$debug cl-$debug sdl-$debug"
985                                         ;;
986                                 *)
987                                         # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
988                                         snowleopardhack=true
989                                         TARGETS="sv-$debug sdl-$debug"
990                                         ;;
991                         esac
992                         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"
993                 else
994                         TARGETS="sv-$debug cl-$debug sdl-$debug"
995                 fi
996                 if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
997                         # if we give the command make the arg "", it will surely fail (invalid filename),
998                         # so better handle it as an empty client option
999                         BAD_TARGETS=" "
1000                         shift
1001                 elif [ -n "$1" ]; then
1002                         BAD_TARGETS=
1003                         TARGETS_SAVE=$TARGETS
1004                         TARGETS=
1005                         for X in $1; do
1006                                 case "$X" in
1007                                         sdl)
1008                                                 TARGETS="$TARGETS sdl-debug"
1009                                                 ;;
1010                                         agl)
1011                                                 TARGETS="$TARGETS cl-debug"
1012                                                 if $snowleopardhack; then
1013                                                         export CC="$CC -arch i386"
1014                                                 fi
1015                                                 ;;
1016                                         glx|wgl)
1017                                                 TARGETS="$TARGETS cl-debug"
1018                                                 ;;
1019                                         dedicated)
1020                                                 TARGETS="$TARGETS sv-debug"
1021                                                 ;;
1022                                         *)
1023                                                 BAD_TARGETS="$BAD_TARGETS $X"
1024                                                 ;;
1025                                 esac
1026                         done
1027                         if [ -n "$TARGETS" ]; then # at least a valid client
1028                                 shift
1029                         else # no valid client, let's assume this option is not meant to be a client then
1030                                 TARGETS=$TARGETS_SAVE
1031                                 BAD_TARGETS=
1032                         fi
1033                 fi
1034                 if [ -z "$MAKEFLAGS" ]; then
1035                         if [ -f /proc/cpuinfo ]; then
1036                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo`+0))
1037                                 if [ $ncpus -gt 1 ]; then
1038                                         MAKEFLAGS=-j$ncpus
1039                                 fi
1040                         fi
1041                         if [ -n "$WE_HATE_OUR_USERS" ]; then
1042                                 MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
1043                         fi
1044                 fi
1045
1046                 verbose cd "$d0/d0_blind_id"
1047                 if ! $compiled0; then
1048                         # compilation of crypto library failed
1049                         # use binaries then, if we can...
1050                         mkdir -p .libs
1051                         if [ -n "$WE_HATE_OUR_USERS" ]; then
1052                                 verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
1053                                 verbose cp "$d0/misc/buildfiles/win32/libd0_rijndael"-* .libs/
1054                                 verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
1055                         else
1056                                 case "`uname`" in
1057                                         Linux)
1058                                                 case `uname -m` in
1059                                                         x86_64)
1060                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
1061                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_rijndael".* .libs/
1062                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
1063                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
1064                                                                 ;;
1065                                                         *86)
1066                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
1067                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_rijndael".* .libs/
1068                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
1069                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
1070                                                                 ;;
1071                                                         *)
1072                                                                 compiled0=true
1073                                                                 ;;
1074                                                 esac
1075                                                 ;;
1076                                         Darwin)
1077                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
1078                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael".* .libs/
1079                                                 ;;
1080                                         *)
1081                                                 compiled0=true
1082                                                 ;;
1083                                 esac
1084                         fi
1085                 fi
1086                 if $compiled0; then
1087                         if $cleand0; then
1088                                 if [ -f Makefile ]; then
1089                                         verbose make $MAKEFLAGS distclean
1090                                 fi
1091                         fi
1092                         if ! [ -f Makefile ]; then
1093                                 verbose sh autogen.sh
1094                                 verbose ./configure
1095                         fi
1096                         verbose make $MAKEFLAGS
1097                 fi
1098
1099                 verbose cd "$d0/fteqcc"
1100                 if $cleanqcc; then
1101                         verbose make $MAKEFLAGS clean
1102                 fi
1103                 verbose make $MAKEFLAGS
1104
1105                 verbose cd "$d0/data/xonotic-data.pk3dir"
1106                 if $cleanqc; then
1107                         verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
1108                 fi
1109                 verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
1110                 # 4 levels up: data, xonotic-data, qcsrc, server
1111
1112                 verbose cd "$d0/darkplaces"
1113                 if [ x"$BAD_TARGETS" = x" " ]; then
1114                         $ECHO "Warning: invalid empty client, default clients will be used."
1115                 fi
1116                 if $cleandp; then
1117                         verbose make $MAKEFLAGS clean
1118                 fi
1119                 for T in $TARGETS; do
1120                         verbose make $MAKEFLAGS STRIP=: "$@" "$T"
1121                 done
1122                 for T in $BAD_TARGETS; do
1123                         $ECHO "Warning: discarded invalid client $T."
1124                 done
1125
1126                 verbose "$SELF" update-maps
1127                 ;;
1128         run)
1129                 if [ -n "$WE_HATE_OUR_USERS" ]; then
1130                         client=
1131                         export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
1132                 elif [ x"`uname`" = x"Darwin" ]; then
1133                         export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS:$d0/d0_blind_id/.libs"
1134                         export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
1135                         client=-sdl
1136                 else
1137                         export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
1138                         client=-sdl
1139                 fi
1140                 case "$1" in
1141                         sdl|glx|agl|dedicated)
1142                                 client=-$1
1143                                 shift
1144                                 ;;
1145                         wgl)
1146                                 client=
1147                                 shift
1148                                 ;;
1149                 esac
1150                 if ! [ -x "darkplaces/darkplaces$client" ]; then
1151                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
1152                                 client=$client.exe
1153                         else
1154                                 $ECHO "Client darkplaces/darkplaces$client not found, aborting"
1155                                 exit 1
1156                         fi
1157                 fi
1158                 set -- "darkplaces/darkplaces$client" -xonotic "$@"
1159
1160                 # if pulseaudio is running: USE IT
1161                 if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
1162                         if ps -C pulseaudio >/dev/null; then
1163                                 if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
1164                                         export SDL_AUDIODRIVER=pulse
1165                                 fi
1166                         fi
1167                 fi
1168
1169                 binary=$1
1170
1171                 if [ x"$USE_GDB" = x"yes" ]; then
1172                         set -- gdb --args "$@"
1173                 elif [ x"$USE_GDB" != x"no" ] && which gdb >/dev/null 2>&1; then
1174                         set -- gdb --batch -x savecore.gdb --args "$@"
1175                 elif which catchsegv >/dev/null 2>&1; then
1176                         set -- catchsegv "$@"
1177                 fi
1178                 rm -f xonotic.core
1179                 "$@" || true
1180                 if [ -f xonotic.core ]; then
1181                         if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
1182                                 gdb "$binary" xonotic.core
1183                         #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
1184                         #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
1185                         #       # somehow send it
1186                         #       rm -f xonotic.core.tar.gz
1187                         else
1188                                 $ECHO "The core dump can be examined later by"
1189                                 $ECHO "  gdb $binary xonotic.core"
1190                         fi
1191                         exit 1
1192                 fi
1193                 ;;
1194         each|foreach)
1195                 keep_going=false
1196                 if [ x"$1" = x"-k" ]; then
1197                         keep_going=true
1198                         shift
1199                 fi
1200                 for d in $repos; do
1201                         if verbose cd "$d0/$d"; then
1202                                 if $keep_going; then
1203                                         verbose "$@" || true
1204                                 else
1205                                         verbose "$@"
1206                                 fi
1207                                 cd "$d0"
1208                         fi
1209                 done
1210                 ;;
1211         save-patches)
1212                 outfile=$1
1213                 patchdir=`mktemp -d -t save-patches.XXXXXX`
1214                 for d in $repos; do
1215                         enter "$d0/$d" verbose
1216                         git branch -v -v | cut -c 3- | {
1217                                 i=0
1218                                 while read -r BRANCH REV UPSTREAM TEXT; do
1219                                         case "$UPSTREAM" in
1220                                                 \[*)
1221                                                         UPSTREAM=${UPSTREAM#\[}
1222                                                         UPSTREAM=${UPSTREAM%\]}
1223                                                         UPSTREAM=${UPSTREAM%:*}
1224                                                         TRACK=true
1225                                                         ;;
1226                                                 *)
1227                                                         UPSTREAM=origin/"`repobranch "$d"`"
1228                                                         TRACK=false
1229                                                         ;;
1230                                         esac
1231                                         if [ x"$REV" = x"->" ]; then
1232                                                 continue
1233                                         fi
1234                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
1235                                                 $ECHO "$d" > "$patchdir/$i/info.txt"
1236                                                 $ECHO "$BRANCH" >> "$patchdir/$i/info.txt"
1237                                                 $ECHO "$UPSTREAM" >> "$patchdir/$i/info.txt"
1238                                                 $ECHO "$TRACK" >> "$patchdir/$i/info.txt"
1239                                                 i=$(($i+1))
1240                                         else
1241                                                 rm -rf "$patchdir/$i"
1242                                         fi
1243                                 done
1244                         }
1245                 done
1246                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
1247                 rm -rf "$patchdir"
1248                 ;;
1249         restore-patches)
1250                 infile=$1
1251                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
1252                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
1253                 # detach the head
1254                 for P in "$patchdir"/*/info.txt; do
1255                         D=${P%/info.txt}
1256                         exec 3<"$P"
1257                         read -r d <&3
1258                         read -r BRANCH <&3
1259                         read -r UPSTREAM <&3
1260                         read -r TRACK <&3
1261                         verbose git checkout HEAD^0
1262                         verbose git branch -D "$BRANCH"
1263                         if [ x"$TRACK" = x"true" ]; then
1264                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
1265                         else
1266                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
1267                         fi
1268                         verbose git am "$D"
1269                 done
1270                 rm -rf "$patchdir"
1271                 ;;
1272         admin-merge)
1273                 branch=$1
1274                 only_delete=false
1275                 case "$branch" in
1276                         -d)
1277                                 branch=
1278                                 only_delete=true
1279                                 ;;
1280                 esac
1281                 t=`mktemp`
1282                 report=""
1283                 reportecho()
1284                 {
1285                         report=$report"$*$LF"
1286                         $ECHO "$*"
1287                 }
1288                 reportecho4()
1289                 {
1290                         report=$report"    $*$LF"
1291                         $ECHO "    $*"
1292                 }
1293                 reportdo4()
1294                 {
1295                         o=`"$@" | sed 's/^/    /' || true`
1296                         reportecho "$o"
1297                 }
1298                 for d in $repos; do
1299                         case "$d" in
1300                                 fteqcc)
1301                                         # sorry, fteqcc repo is managed manually
1302                                         continue
1303                                         ;;
1304                         esac
1305                         enter "$d0/$d" verbose
1306                         base="`repobranch "$d"`"
1307                         reportecho "In $d:"
1308                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
1309                                 case "${ref#refs/remotes/origin/}" in
1310                                         "$base")
1311                                                 continue
1312                                                 ;;
1313                                         HEAD|master)
1314                                                 continue
1315                                                 ;;
1316                                         */*)
1317                                                 ;;
1318                                         *)
1319                                                 continue
1320                                                 ;;
1321                                 esac
1322                                 if [ -n "$branch" ]; then
1323                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1324                                                 continue
1325                                         fi
1326                                 fi
1327                                 case "$base" in
1328                                         master)
1329                                                 realbase=$base
1330                                                 ;;
1331                                         *)
1332                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1333                                                 l1=`git rev-list master.."$ref" | wc -l`
1334                                                 if [ $l0 -gt $l1 ]; then
1335                                                         realbase=master
1336                                                 else
1337                                                         realbase=$base
1338                                                 fi
1339                                                 ;;
1340                                 esac
1341                                 reportecho "  Branch $ref:"
1342                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1343                                 logdata=`git log --color "$realbase".."$ref"`
1344                                 if [ -z "$logdata" ]; then
1345                                         reportecho4 "--> not merging, no changes vs master"
1346                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1347                                                 git push origin :"${ref#refs/remotes/origin/}"
1348                                                 reportecho4 "--> branch deleted"
1349                                         fi
1350                                 else
1351                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1352                                         if [ -z "$diffdata" ]; then
1353                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1354                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ $ECHO "$logdata"; } | less -r'; then
1355                                                         git push origin :"${ref#refs/remotes/origin/}"
1356                                                         reportecho4 "--> branch deleted"
1357                                                 fi
1358                                         elif $only_delete; then
1359                                                 reportecho4 "--> skipped in delete-only run"
1360                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1361                                                 reportdo4 $ECHO "$note"
1362                                                 reportecho4 "--> not merging, already had this one rejected before"
1363                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ $ECHO "$logdata"; $ECHO "$diffdata"; } | less -r'; then
1364                                                 git checkout "$realbase"
1365                                                 org=`git rev-parse HEAD`
1366                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1367                                                         git reset --hard "$org"
1368                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1369                                                         reportdo4 cat "$t"
1370                                                         reportecho4 "--> merge failed"
1371                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1372                                                         git reset --hard "$org"
1373                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1374                                                         reportdo4 cat "$t"
1375                                                         reportecho4 "--> compile failed"
1376                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1377                                                         git reset --hard "$org"
1378                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1379                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1380                                                         if [ x"$note" = x"del" ]; then
1381                                                                 git push origin :"${ref#refs/remotes/origin/}"
1382                                                                 reportecho4 "--> test failed, branch deleted"
1383                                                         elif [ -n "$note" ]; then
1384                                                                 reportdo4 $ECHO "$note"
1385                                                                 reportecho4 "--> test failed"
1386                                                         else
1387                                                                 reportecho4 "--> test failed, postponed"
1388                                                         fi
1389                                                 else
1390                                                         # apply crlf, or other cleanup filters (non-behavioural changes)
1391                                                         git reset --hard
1392                                                         find . -type f -exec touch {} \;
1393                                                         git commit -a --amend -C HEAD || true # don't fail if nothing to commit
1394
1395                                                         $ECHO "MERGING"
1396                                                         case ",`repoflags "$d"`," in
1397                                                                 *,svn,*)
1398                                                                         # we do quite a mess here... luckily we know $org
1399                                                                         git fetch # svn needs to be current
1400                                                                         git rebase -i --onto origin/master "$org"
1401                                                                         git svn dcommit --add-author-from
1402                                                                         git reset --hard "$org"
1403                                                                         ;;
1404                                                                 *)
1405                                                                         git push origin HEAD
1406                                                                         ;;
1407                                                         esac
1408                                                         reportecho4 "--> MERGED"
1409                                                         if yesno "Delete original branch \"$ref\"?"; then
1410                                                                 git push origin :"${ref#refs/remotes/origin/}"
1411                                                                 reportecho4 "--> branch deleted"
1412                                                         fi
1413                                                 fi
1414                                         else
1415                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1416                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1417                                                 if [ x"$note" = x"del" ]; then
1418                                                         git push origin :"${ref#refs/remotes/origin/}"
1419                                                         reportecho4 "--> branch deleted"
1420                                                 elif [ -n "$note" ]; then
1421                                                         reportdo4 $ECHO "$note"
1422                                                         reportecho4 "--> rejected"
1423                                                 else
1424                                                         reportecho4 "--> postponed"
1425                                                 fi
1426                                         fi
1427                                 fi
1428                                 reportecho ""
1429                         done
1430                         reportecho ""
1431                 done
1432                 rm -f "$t"
1433                 $ECHO "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1434                 ;;
1435         clean)
1436                 "$SELF" fix_config
1437                 "$SELF" update -N
1438                 force=false
1439                 gotoupstream=false
1440                 fetchupstream=false
1441                 gotomaster=false
1442                 rmuntracked=false
1443                 killbranches=false
1444                 # usage:
1445                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1446                 #   ./all clean --reclone
1447                 found=false
1448                 for X in "$@"; do
1449                         if [ x"$X" = x"--reclone" ]; then
1450                                 force=true
1451                                 fetchupstream=true
1452                                 gotoupstream=true
1453                                 gotomaster=true
1454                                 rmuntracked=true
1455                                 killbranches=true
1456                         elif [ x"$X" = x"-f" ]; then
1457                                 force=true
1458                         elif [ x"$X" = x"-u" ]; then
1459                                 gotoupstream=true
1460                         elif [ x"$X" = x"-U" ]; then
1461                                 gotoupstream=true
1462                                 fetchupstream=true
1463                         elif [ x"$X" = x"-fu" ]; then
1464                                 force=true
1465                                 gotoupstream=true
1466                         elif [ x"$X" = x"-fU" ]; then
1467                                 force=true
1468                                 gotoupstream=true
1469                                 fetchupstream=true
1470                         elif [ x"$X" = x"-m" ]; then
1471                                 gotomaster=true
1472                         elif [ x"$X" = x"-r" ]; then
1473                                 rmuntracked=true
1474                         elif [ x"$X" = x"-D" ]; then
1475                                 killbranches=true
1476                         elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
1477                                 msg ''
1478                                 msg "        _____"
1479                                 msg "    ,--'-\\P/\`\\  FFFFFFF"
1480                                 msg " __/_    B/,-.\\  FFFFFFF"
1481                                 msg " /  _\\  (//  O\\\\  FFFFFF"
1482                                 msg "| (O  \`) _\\._ _)\\  FFFUU"
1483                                 msg "| |___/.^d0~~\"\\  \\ UUUU"
1484                                 msg "|     |\`~'     \\ |  UUUU"
1485                                 msg "|     |    __,C>|| UUUU"
1486                                 msg "\\    /_ ,-/,-'   |  UUUU"
1487                                 msg " \\\\_ \\_>~'      /  UUUU-"
1488                                 msg ''
1489                         else
1490                                 msg "Unknown arg: $X"
1491                         fi
1492                         found=true
1493                 done
1494                 if ! $found; then
1495                         rmuntracked=true
1496                 fi
1497                 for d in $repos; do
1498                         verbose cd "$d0/$d"
1499                         if $gotoupstream; then
1500                                 if ! $force; then
1501                                         msg "Must also use -f (delete local changes) when using -u"
1502                                         exit 1
1503                                 fi
1504                                 if $gotomaster; then
1505                                         if $fetchupstream; then
1506                                                 verbose git fetch origin
1507                                                 verbose git remote prune origin
1508                                         fi
1509                                         verbose git checkout -f "`repobranch "$d"`"
1510                                         verbose git reset --hard origin/"`repobranch "$d"`"
1511                                 else
1512                                         r=`git symbolic-ref HEAD`
1513                                         r=${r#refs/heads/}
1514                                         rem=`git config "branch.$r.remote" || $ECHO origin`
1515                                         bra=`git config "branch.$r.merge" || $ECHO "$r"`
1516                                         upstream="$rem/${bra#refs/heads/}"
1517                                         if $fetchupstream; then
1518                                                 verbose git fetch "$rem"
1519                                                 verbose git remote prune "$rem"
1520                                         fi
1521                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1522                                                 upstream="origin/`repobranch "$d"`"
1523                                         fi
1524                                         verbose git reset --hard "$upstream"
1525                                 fi
1526                         elif $gotomaster; then
1527                                 if $force; then
1528                                         verbose git checkout -f "`repobranch "$d"`"
1529                                         verbose git reset --hard
1530                                 else
1531                                         verbose git checkout "`repobranch "$d"`"
1532                                 fi
1533                         elif $force; then
1534                                 verbose git reset --hard
1535                         fi
1536                         if $rmuntracked; then
1537                                 case "$d" in
1538                                         .)
1539                                                 verbose git clean -df || true
1540                                                 ;;
1541                                         *)
1542                                                 verbose git clean -xdf || true
1543                                                 ;;
1544                                 esac
1545                         fi
1546                         if $killbranches; then
1547                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1548                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1549                                                 verbose git branch -D "${B#refs/heads/}"
1550                                         fi
1551                                 done
1552                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
1553                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch --track "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1554                         fi
1555                         checkself "$cmd" "$@"
1556                 done
1557                 ;;
1558
1559         # release building goes here
1560         release-prepare)
1561                 #"$SELF" each git clean -fxd
1562                 case "$RELEASETYPE" in
1563                         '')
1564                                 $ECHO >&2 -n "$ESC[2J$ESC[H"
1565                                 msg ""
1566                                 msg ""
1567                                 msg ""
1568                                 msg ""
1569                                 msg ""
1570                                 msg ""
1571                                 msg "        +---------------------------------------------------------.---+"
1572                                 msg "        | NOTE                                                    | X |"
1573                                 msg "        +---------------------------------------------------------^---+"
1574                                 msg "        |   ____                                                      |"
1575                                 msg "        |  /    \  This is the official release build system.         |"
1576                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1577                                 msg "        | | STOP | you are not supposed to use this script and should |"
1578                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1579                                 msg "        |  \____/  and game code.                                     |"
1580                                 msg "        |                                                             |"
1581                                 msg "        |                      [ I understand ]                       |"
1582                                 msg "        +-------------------------------------------------------------+"
1583                                 sleep 10
1584                                 # A LOT of build infrastructure is required:
1585                                 # - vorbis-tools
1586                                 # - ImageMagick
1587                                 # - .ssh/config must be configured so the following
1588                                 #   host names are reachable and have a compile
1589                                 #   infrastructure set up:
1590                                 #   - xonotic-build-linux32 (with gcc on x86)
1591                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1592                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1593                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1594                                 #     and x86_64-w64-mingw32-g++)
1595                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1596                                 # - AMD Compressonator installed in WINE
1597                                 # - ResEdit installed in WINE
1598                                 # - a lot of other requirements you will figure out
1599                                 #   while reading the error messages
1600                                 # - environment variable RELEASETYPE set
1601                                 # - optionally, environment variable RELEASEDATE set
1602                                 #   (YYYYMMDD)
1603                                 exit 1
1604                                 ;;
1605                         release)
1606                                 msg "Building a FINISHED RELEASE"
1607                                 ;;
1608                         *)
1609                                 msg "Building a $RELEASETYPE"
1610                                 ;;
1611                 esac
1612                 verbose rm -rf Xonotic Xonotic*.zip
1613                 verbose mkdir -p Xonotic
1614                 if [ -n "$RELEASEDATE" ]; then
1615                         verbose $ECHO "$RELEASEDATE" > Xonotic/stamp.txt
1616                 else
1617                         verbose date +%Y%m%d > Xonotic/stamp.txt
1618                 fi
1619                 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
1620                 (
1621                         verbose cd Xonotic
1622                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc source/d0_blind_id mapping
1623                         verbose rm -rf misc/builddeps
1624                         verbose mv misc/buildfiles/win32 bin32 || true
1625                         verbose mv bin32/SDL.dll . || true
1626                         verbose mv misc/buildfiles/win64 bin64 || true
1627                         verbose mv misc/buildfiles/osx/* . || true
1628                         verbose rm -rf misc/buildfiles
1629                         verbose rm -rf misc/pki
1630                 )
1631                 release_git_extract_dir "darkplaces" "Xonotic/source/darkplaces" .
1632                 release_git_extract_dir "fteqcc" "Xonotic/source/fteqcc" .
1633                 release_git_extract_dir "data/xonotic-data.pk3dir" "Xonotic/source" qcsrc Makefile
1634                 release_git_extract_dir "d0_blind_id" "Xonotic/source/d0_blind_id" .
1635                 (
1636                         verbose cd Xonotic/source/d0_blind_id
1637                         verbose sh autogen.sh
1638                 )
1639                 rm -f Xonotic/key_15.d0pk
1640                 {
1641                         verbose cd Xonotic/mapping
1642                         verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20110701.tar.bz2
1643                         verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20110701-win32-7z.exe
1644                         for X in *-7z.exe; do
1645                                 7za x "$X"
1646                                 rm -f "$X"
1647                         done
1648                         # TODO possibly include other tools?
1649                 }
1650                 ;;
1651         release-compile-run)
1652                 host=$1
1653                 buildpath=$2
1654                 maketargets=$3
1655                 makeflags=$4
1656                 srcdir=$5
1657                 depsdir=$6
1658                 targetfiles=$7
1659                 set -x
1660                 if [ -n "$targetfiles" ]; then
1661                         case " $HOSTS_THAT_ARE_DISABLED " in
1662                                 *\ $host\ *)
1663                                         exit
1664                                         ;;
1665                         esac
1666                         case " $HOSTS_THAT_ARE_MYSELF " in
1667                                 *\ $host\ *)
1668                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1669                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1670                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1671                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1672                                         for f in $targetfiles; do
1673                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1674                                         done
1675                                         ;;
1676                                 *)
1677                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1678                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1679                                         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"
1680                                         for f in $targetfiles; do
1681                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1682                                         done
1683                                         ;;
1684                         esac
1685                         # now rebrand the binaries...
1686                         for f in $targetfiles; do
1687                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1688                                 case "${f##*:}" in
1689                                         Xonotic/xonotic*.exe)
1690                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1691                                                 ;;
1692                                 esac
1693                         done
1694                 fi
1695                 ;;
1696         release-compile)
1697                 suffix=$1
1698                 makeflags=$2
1699                 fteqcc_maketargets=$3
1700                 fteqcc_files=$4
1701                 darkplaces_maketargets=$5
1702                 darkplaces_files=$6
1703                 host=xonotic-build-$suffix
1704                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1705                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1706                 ;;
1707         release-engine-win32)
1708                 verbose "$SELF" release-compile win32 \
1709                         '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' \
1710                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1711                         '' ''
1712                 verbose "$SELF" release-compile win32 \
1713                         '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' \
1714                         '' '' \
1715                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1716                 ;;
1717         release-engine-win64)
1718                 verbose "$SELF" release-compile win64 \
1719                         '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' \
1720                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1721                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1722                 verbose "$SELF" release-compile win64 \
1723                         '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' \
1724                         '' '' \
1725                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1726                 ;;
1727         release-engine-osx)
1728                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1729                 verbose "$SELF" release-compile osx \
1730                         '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"' \
1731                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1732                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1733                 ;;
1734         release-engine-linux32)
1735                 verbose "$SELF" release-compile linux32 \
1736                         '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' \
1737                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1738                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1739                 ;;
1740         release-engine-linux64)
1741                 verbose "$SELF" release-compile linux64 \
1742                         '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' \
1743                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1744                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1745                 ;;
1746         release-engine)
1747                 verbose "$SELF" release-engine-linux32 &
1748                 verbose "$SELF" release-engine-linux64 &
1749                 verbose "$SELF" release-engine-win32 &
1750                 verbose "$SELF" release-engine-win64 &
1751                 verbose "$SELF" release-engine-osx &
1752                 wait %1
1753                 wait %2
1754                 wait %3
1755                 wait %4
1756                 wait %5
1757                 wait
1758                 ;;
1759         release-maps)
1760                 verbose "$SELF" update-maps
1761                 ;;
1762         release-qc)
1763                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1764                 verbose rm -f Xonotic/source/qcsrc/*/fteqcc.log
1765                 ;;
1766         release-buildpk3-transform-raw)
1767                 dir=$1
1768                 ;;
1769         release-buildpk3-transform-normal)
1770                 dir=$1
1771                 verbose cd "$dir"
1772                 # texture: convert to jpeg and dds
1773                 verbose export do_jpeg=true
1774                 verbose export jpeg_qual_rgb=97
1775                 verbose export jpeg_qual_a=99
1776                 verbose export do_dds=false
1777                 verbose export do_ogg=false
1778                 verbose export del_src=true
1779                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1780                 ;;
1781         release-buildpk3-transform-normaldds)
1782                 dir=$1
1783                 verbose cd "$dir"
1784                 # texture: convert to jpeg and dds
1785                 # music: reduce bitrate
1786                 verbose export do_jpeg=false
1787                 verbose export do_jpeg_if_not_dds=true
1788                 verbose export jpeg_qual_rgb=95
1789                 verbose export jpeg_qual_a=99
1790                 verbose export do_dds=true
1791                 verbose export dds_flags=
1792                 verbose export do_ogg=true
1793                 verbose export del_src=true
1794                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1795                 ;;
1796         release-buildpk3-transform-low)
1797                 dir=$1
1798                 verbose cd "$dir"
1799                 # texture: convert to jpeg and dds
1800                 # music: reduce bitrate
1801                 verbose export do_jpeg=true
1802                 verbose export jpeg_qual_rgb=80
1803                 verbose export jpeg_qual_a=97
1804                 verbose export do_dds=false
1805                 verbose export do_ogg=true
1806                 verbose export ogg_qual=1
1807                 verbose export del_src=true
1808                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1809                 ;;
1810         release-buildpk3-transform-lowdds)
1811                 dir=$1
1812                 verbose cd "$dir"
1813                 # texture: convert to jpeg and dds
1814                 # music: reduce bitrate
1815                 verbose export do_jpeg=false
1816                 verbose export do_jpeg_if_not_dds=true
1817                 verbose export jpeg_qual_rgb=80
1818                 verbose export jpeg_qual_a=99
1819                 verbose export do_dds=true
1820                 verbose export dds_flags=
1821                 verbose export do_ogg=true
1822                 verbose export ogg_qual=1
1823                 verbose export del_src=true
1824                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1825                 ;;
1826         release-buildpk3)
1827                 src=$1
1828                 dst=$2
1829                 transform=$3
1830                 case "$dst" in
1831                         /*)
1832                                 ;;
1833                         */)
1834                                 dst="$PWD/$dst"
1835                                 ;;
1836                 esac
1837                 release_timereport
1838                 verbose rm -rf Xonotic/temp
1839                 release_timereport "deleted temp directory"
1840                 verbose mkdir -p Xonotic/temp
1841                 release_git_extract_dir "$src" "Xonotic/temp" .
1842                 release_timereport "extracted data"
1843                 verbose cd Xonotic/temp
1844                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1845                         verbose cp ../source/progs.dat .
1846                         verbose cp ../source/csprogs.dat .
1847                         verbose cp ../source/menu.dat .
1848                         verbose rm -rf qcsrc
1849                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1850                         major=$(($gv / 10000))
1851                         minor=$((($gv / 100) - ($major * 100)))
1852                         patch=$(($gv - ($major * 10000) - ($minor * 100)))
1853                         versionstr="$major.$minor.$patch"
1854                         case "$RELEASETYPE" in
1855                                 release)
1856                                         ;;
1857                                 *)
1858                                         versionstr="$versionstr$RELEASETYPE"
1859                                         ;;
1860                         esac
1861                         if [ $gv -lt 900 ]; then
1862                                 # pre-1.0: compatible with any other pre-1.0
1863                                 verbose sed "
1864                                         s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1865                                         s/^gameversion_min [0-9]*/gameversion_min     0/;
1866                                         s/^gameversion_max [0-9]*/gameversion_max  9999/;
1867                                 " < defaultXonotic.cfg > defaultXonotic.cfg.new
1868                         else
1869                                 # >= 1.0
1870                                 verbose sed "
1871                                         s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1872                                         s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1873                                         s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1874                                 " < defaultXonotic.cfg > defaultXonotic.cfg.new
1875                         fi
1876                         mv defaultXonotic.cfg.new defaultXonotic.cfg
1877                         case "$RELEASETYPE" in
1878                                 release)
1879                                         echo "" >> defaultXonotic.cfg
1880                                         echo "// nicer menu" >> defaultXonotic.cfg
1881                                         echo "set menu_watermark \"\"" >> defaultXonotic.cfg
1882                                         ;;
1883                         esac
1884                         (
1885                                 verbose cd gfx/menu/luminos
1886                                 verbose rm -f background_l2.tga background_ingame_l2.tga
1887                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1888                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1889                                 verbose rm background_l2.svg
1890                         )
1891                 fi
1892                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1893                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1894                                 if [ -f "$X" ]; then
1895                                         verbose unzip "$X"
1896                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1897                                 fi
1898                         done
1899                 fi
1900                 verbose export git_src_repo="$d0/$src" # skip hash-object
1901                 release_timereport "processed data"
1902                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1903                 release_timereport "transformed data"
1904                 verbose mkzipr "../../$dst" *
1905                 release_timereport "zipped data"
1906                 verbose cd ../..
1907                 verbose rm -rf Xonotic/temp
1908                 release_timereport "deleted temp directory again"
1909                 ;;
1910         release-buildpk3s)
1911                 stamp=`cat Xonotic/stamp.txt`
1912                 src=$1
1913                 shift
1914                 dst=${src%.pk3dir}
1915                 case "$dst" in
1916                         data/xonotic-*)
1917                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1918                                 ;;
1919                         *)
1920                                 dst="$dst-$stamp"
1921                                 ;;
1922                 esac
1923                 while [ "$#" -gt 1 ]; do
1924                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1925                         shift
1926                         shift
1927                 done
1928                 ;;
1929         release-pack)
1930                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir                  raw ''
1931                 verbose "$SELF" release-buildpk3s data/font-xolonium.pk3dir                     raw ''
1932                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal '-high'        low '-low' normaldds ''
1933                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal '-high'        low '-low' normaldds ''
1934                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                     raw '' low '-low'
1935                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir  normal '-high'                   normaldds ''
1936                 ;;
1937         release-pack-needsx11)
1938                 case "$DISPLAY" in
1939                         '')
1940                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1941                                 ;;
1942                         *)
1943                                 verbose "$SELF" release-pack
1944                                 ;;
1945                 esac
1946                 ;;
1947         release-zip)
1948                 stamp=`cat Xonotic/stamp.txt`
1949                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1950                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1951                 # let's pass crypto import laws of some nasty countries
1952                 crypto_libs=`find Xonotic -name \*d0_rijndael\*.so -o -name \*d0_rijndael\*.dylib -o -name \*d0_rijndael\*.dll -o -name \*d0_rijndael\*.c`
1953                 if [ -n "$crypto_libs" ]; then
1954                         verbose mkzip Xonotic-$stamp-crypto.zip \
1955                                 $crypto_libs \
1956                                 Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
1957                         rm -f $crypto_libs
1958                 fi
1959                 # build the archives
1960                 verbose mkzip Xonotic-$stamp-engine.zip \
1961                         Xonotic/*.dll \
1962                         Xonotic/bin32/*.dll \
1963                         Xonotic/bin64/*.dll \
1964                         Xonotic/*.app \
1965                         Xonotic/xonotic-* \
1966                         Xonotic/xonotic.exe \
1967                         Xonotic/source/darkplaces/ \
1968                         Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
1969                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1970                 verbose mkzip Xonotic-$stamp-common.zip \
1971                         Xonotic/source/fteqcc/ \
1972                         Xonotic/source/qcsrc/ \
1973                         Xonotic/Docs \
1974                         Xonotic/misc \
1975                         Xonotic/fteqcc \
1976                         Xonotic/server \
1977                         Xonotic/key_0.d0pk \
1978                         Xonotic/data/font-nimbussansl-$stamp.pk3 \
1979                         Xonotic/data/font-xolonium-$stamp.pk3
1980                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1981                 verbose mkzip0 Xonotic-$stamp.zip \
1982                         Xonotic/data/xonotic-$stamp-data.pk3 \
1983                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1984                         Xonotic/data/xonotic-$stamp-music.pk3 \
1985                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1986                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1987                 verbose mkzip0 Xonotic-$stamp-low.zip \
1988                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1989                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1990                         Xonotic/data/xonotic-$stamp-music-low.pk3
1991                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1992                 verbose mkzip Xonotic-$stamp-high.zip \
1993                         Xonotic/mapping
1994                 verbose mkzip0 Xonotic-$stamp-high.zip \
1995                         Xonotic/data/xonotic-$stamp-data-high.pk3 \
1996                         Xonotic/data/xonotic-$stamp-maps-high.pk3 \
1997                         Xonotic/data/xonotic-$stamp-music.pk3 \
1998                         Xonotic/data/xonotic-$stamp-nexcompat-high.pk3
1999                 verbose mkzip Xonotic-$stamp-mappingsupport.zip \
2000                         Xonotic/mapping
2001                 verbose mkzip0 Xonotic-$stamp-mappingsupport.zip \
2002                         Xonotic/data/xonotic-$stamp-maps-low.pk3
2003                 ;;
2004         release)
2005                 verbose "$SELF" release-prepare
2006                 verbose "$SELF" release-maps
2007                 verbose "$SELF" release-engine
2008                 verbose "$SELF" release-qc
2009                 verbose "$SELF" release-pack-needsx11
2010                 verbose "$SELF" release-zip
2011                 ;;
2012
2013         *)
2014                 $ECHO "Usage:"
2015                 $ECHO "  $SELF admin-merge [<branch>]"
2016                 $ECHO "  $SELF branch <branch>"
2017                 $ECHO "  $SELF branch <remote> <branch> [<srcbranch>]"
2018                 $ECHO "  $SELF branches"
2019                 $ECHO "  $SELF checkout|switch <branch>"
2020                 $ECHO "  $SELF checkout|switch <remote>/<branch>"
2021                 $ECHO "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
2022                 $ECHO "  $SELF clean --reclone"
2023                 $ECHO "  $SELF compile [-c] [-r|-p] [-0] [sdl|glx|wgl|agl|dedicated]"
2024                 $ECHO "  $SELF each|foreach [-k] command..."
2025                 $ECHO "  $SELF fix_upstream_rebase"
2026                 $ECHO "  $SELF keygen"
2027                 $ECHO "  $SELF merge"
2028                 $ECHO "  $SELF push|commit [-s]"
2029                 $ECHO "  $SELF restore-patches"
2030                 $ECHO "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
2031                 $ECHO "  $SELF save-patches"
2032                 $ECHO "  $SELF update-maps"
2033                 $ECHO "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
2034                 ;;
2035 esac