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