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