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