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