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