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