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