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