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