]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
don't fail if nothing to commit
[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                         else
1225                                 break
1226                         fi
1227                         found=true
1228                         shift
1229                 done
1230                 if ! $found; then
1231                         rmuntracked=true
1232                 fi
1233                 for d in $repos; do
1234                         verbose cd "$d0/$d"
1235                         if $gotoupstream; then
1236                                 if ! $force; then
1237                                         msg "Must also use -f (delete local changes) when using -u"
1238                                         exit 1
1239                                 fi
1240                                 if $gotomaster; then
1241                                         if $fetchupstream; then
1242                                                 verbose git fetch origin
1243                                                 verbose git remote prune origin
1244                                         fi
1245                                         verbose git checkout -f "`repobranch "$d"`"
1246                                         verbose git reset --hard origin/"`repobranch "$d"`"
1247                                 else
1248                                         r=`git symbolic-ref HEAD`
1249                                         r=${r#refs/heads/}
1250                                         rem=`git config "branch.$r.remote" || echo origin`
1251                                         bra=`git config "branch.$r.merge" || echo "$r"`
1252                                         upstream="$rem/${bra#refs/heads/}"
1253                                         if $fetchupstream; then
1254                                                 verbose git fetch "$rem"
1255                                                 verbose git remote prune "$rem"
1256                                         fi
1257                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1258                                                 upstream="origin/`repobranch "$d"`"
1259                                         fi
1260                                         verbose git reset --hard "$upstream"
1261                                 fi
1262                         elif $gotomaster; then
1263                                 if $force; then
1264                                         verbose git checkout -f "`repobranch "$d"`"
1265                                         verbose git reset --hard
1266                                 else
1267                                         verbose git checkout "`repobranch "$d"`"
1268                                 fi
1269                         elif $force; then
1270                                 verbose git reset --hard
1271                         fi
1272                         if $rmuntracked; then
1273                                 case "$d" in
1274                                         .)
1275                                                 verbose git clean -df
1276                                                 ;;
1277                                         *)
1278                                                 verbose git clean -xdf
1279                                                 ;;
1280                                 esac
1281                         fi
1282                         if $killbranches; then
1283                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1284                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1285                                                 verbose git branch -D "${B#refs/heads/}"
1286                                         fi
1287                                 done
1288                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch -t master origin/master || true
1289                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch -t "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1290                         fi
1291                         checkself "$cmd" "$@"
1292                 done
1293                 ;;
1294
1295         # release building goes here
1296         release-prepare)
1297                 #"$SELF" each git clean -fxd
1298                 case "$RELEASETYPE" in
1299                         beta)
1300                                 msg "Building a BETA"
1301                                 ;;
1302                         release)
1303                                 msg "Building a RELEASE"
1304                                 ;;
1305                         *)
1306                                 echo >&2 -n "$ESC[2J$ESC[H"
1307                                 msg ""
1308                                 msg ""
1309                                 msg ""
1310                                 msg ""
1311                                 msg ""
1312                                 msg ""
1313                                 msg "        +---------------------------------------------------------.---+"
1314                                 msg "        | NOTE                                                    | X |"
1315                                 msg "        +---------------------------------------------------------^---+"
1316                                 msg "        |   ____                                                      |"
1317                                 msg "        |  /    \  This is the official release build system.         |"
1318                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1319                                 msg "        | | STOP | you are not supposed to use this script and should |"
1320                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1321                                 msg "        |  \____/  and game code.                                     |"
1322                                 msg "        |                                                             |"
1323                                 msg "        |                      [ I understand ]                       |"
1324                                 msg "        +-------------------------------------------------------------+"
1325                                 sleep 10
1326                                 # A LOT of build infrastructure is required:
1327                                 # - vorbis-tools
1328                                 # - ImageMagick
1329                                 # - .ssh/config must be configured so the following
1330                                 #   host names are reachable and have a compile
1331                                 #   infrastructure set up:
1332                                 #   - xonotic-build-linux32 (with gcc on x86)
1333                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1334                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1335                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1336                                 #     and x86_64-w64-mingw32-g++)
1337                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1338                                 # - AMD Compressonator installed in WINE
1339                                 # - ResEdit installed in WINE
1340                                 # - a lot of other requirements you will figure out
1341                                 #   while reading the error messages
1342                                 # - environment variable RELEASETYPE set
1343                                 # - optionally, environment variable RELEASEDATE set
1344                                 #   (YYYYMMDD)
1345                                 exit 1
1346                                 ;;
1347                 esac
1348                 verbose rm -rf Xonotic Xonotic*.zip
1349                 verbose mkdir -p Xonotic
1350                 if [ -n "$RELEASEDATE" ]; then
1351                         verbose echo "$RELEASEDATE" > Xonotic/stamp.txt
1352                 else
1353                         verbose date +%Y%m%d > Xonotic/stamp.txt
1354                 fi
1355                 verbose git archive --format=tar HEAD -- Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk | {
1356                         verbose cd Xonotic
1357                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc
1358                         verbose tar xvf -
1359                         verbose rm -rf misc/builddeps
1360                         verbose mv misc/buildfiles/win32/* . || true
1361                         verbose mv misc/buildfiles/win64 bin64 || true
1362                         verbose mv misc/buildfiles/osx/* . || true
1363                         verbose rm -rf misc/buildfiles
1364                         verbose rm -rf misc/pki
1365                 }
1366                 {
1367                         verbose cd darkplaces
1368                         verbose git archive --format=tar HEAD
1369                 } | {
1370                         verbose cd Xonotic/source/darkplaces
1371                         verbose tar xvf -
1372                 }
1373                 {
1374                         verbose cd fteqcc
1375                         verbose git archive --format=tar HEAD
1376                 } | {
1377                         verbose cd Xonotic/source/fteqcc
1378                         verbose tar xvf -
1379                 }
1380                 {
1381                         verbose cd data/xonotic-data.pk3dir
1382                         verbose git archive --format=tar HEAD -- qcsrc Makefile
1383                 } | {
1384                         verbose cd Xonotic/source
1385                         verbose tar xvf -
1386                 }
1387                 rm -f Xonotic/key_15.d0pk
1388                 ;;
1389         release-compile-run)
1390                 host=$1
1391                 buildpath=$2
1392                 maketargets=$3
1393                 makeflags=$4
1394                 srcdir=$5
1395                 depsdir=$6
1396                 targetfiles=$7
1397                 set -x
1398                 if [ -n "$targetfiles" ]; then
1399                         case " $HOSTS_THAT_ARE_DISABLED " in
1400                                 *\ $host\ *)
1401                                         exit
1402                                         ;;
1403                         esac
1404                         case " $HOSTS_THAT_ARE_MYSELF " in
1405                                 *\ $host\ *)
1406                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1407                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1408                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1409                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1410                                         for f in $targetfiles; do
1411                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1412                                         done
1413                                         ;;
1414                                 *)
1415                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1416                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1417                                         verbose ssh "$host" "ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
1418                                         for f in $targetfiles; do
1419                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1420                                         done
1421                                         ;;
1422                         esac
1423                         # now rebrand the binaries...
1424                         for f in $targetfiles; do
1425                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1426                                 case "${f##*:}" in
1427                                         xonotic*.exe)
1428                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1429                                                 (
1430                                                         d=`mktemp -d -t rebrand.XXXXXX`
1431                                                         cd "$d"
1432                                                         echo "-mygames" > darkplaces.opt
1433                                                         zip -9r darkplaces.zip darkplaces.opt
1434                                                         cat darkplaces.zip
1435                                                         cd "$d0"
1436                                                         rm -rf "$d"
1437                                                 ) >> "${f##*:}"
1438                                                 ;;
1439                                 esac
1440                         done
1441                 fi
1442                 ;;
1443         release-compile)
1444                 suffix=$1
1445                 makeflags=$2
1446                 fteqcc_maketargets=$3
1447                 fteqcc_files=$4
1448                 darkplaces_maketargets=$5
1449                 darkplaces_files=$6
1450                 host=xonotic-build-$suffix
1451                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1452                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1453                 ;;
1454         release-engine-win32)
1455                 verbose "$SELF" release-compile win32 \
1456                         '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' \
1457                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1458                         '' ''
1459                 verbose "$SELF" release-compile win32 \
1460                         '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' \
1461                         '' '' \
1462                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1463                 ;;
1464         release-engine-win64)
1465                 verbose "$SELF" release-compile win64 \
1466                         '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' \
1467                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1468                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1469                 verbose "$SELF" release-compile win64 \
1470                         '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' \
1471                         '' '' \
1472                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1473                 ;;
1474         release-engine-osx)
1475                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1476                 verbose "$SELF" release-compile osx \
1477                         '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"' \
1478                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1479                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic-SDL.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1480                 verbose "$SELF" release-compile osx \
1481                         '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"' \
1482                         '' '' \
1483                         'cl-release' 'darkplaces-agl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-agl-bin'
1484                 ;;
1485         release-engine-linux32)
1486                 verbose "$SELF" release-compile linux32 \
1487                         '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' \
1488                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1489                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1490                 ;;
1491         release-engine-linux64)
1492                 verbose "$SELF" release-compile linux64 \
1493                         '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' \
1494                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1495                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1496                 ;;
1497         release-engine)
1498                 verbose "$SELF" release-engine-linux32 &
1499                 verbose "$SELF" release-engine-linux64 &
1500                 verbose "$SELF" release-engine-win32 &
1501                 verbose "$SELF" release-engine-win64 &
1502                 verbose "$SELF" release-engine-osx &
1503                 wait %1
1504                 wait %2
1505                 wait %3
1506                 wait %4
1507                 wait %5
1508                 wait
1509                 ;;
1510         release-maps)
1511                 verbose "$SELF" update-maps
1512                 ;;
1513         release-qc)
1514                 case "$RELEASETYPE" in
1515                         beta)
1516                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1517                                 # back out of: source/qcsrc/server
1518                                 ;;
1519                         release)
1520                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 FTEQCCFLAGS_WATERMARK= clean all
1521                                 ;;
1522                 esac
1523                 verbose rm -f Xonotic/source/*/fteqcc.log
1524                 ;;
1525         release-buildpk3-transform-raw)
1526                 dir=$1
1527                 ;;
1528         release-buildpk3-transform-normal)
1529                 dir=$1
1530                 verbose cd "$dir"
1531                 # texture: convert to jpeg and dds
1532                 verbose export do_jpeg=true
1533                 verbose export jpeg_qual_rgb=95
1534                 verbose export jpeg_qual_a=99
1535                 verbose export do_dds=true
1536                 verbose export dds_flags=
1537                 verbose export do_ogg=false
1538                 verbose export del_src=true
1539                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1540                 ;;
1541         release-buildpk3-transform-low)
1542                 dir=$1
1543                 verbose cd "$dir"
1544                 # texture: convert to jpeg and dds
1545                 # music: reduce bitrate
1546                 verbose export do_jpeg=true
1547                 verbose export jpeg_qual_rgb=80
1548                 verbose export jpeg_qual_a=99
1549                 verbose export do_dds=false
1550                 verbose export do_ogg=true
1551                 verbose export ogg_qual=1
1552                 verbose export del_src=true
1553                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1554                 ;;
1555         release-buildpk3-transform-lowdds)
1556                 dir=$1
1557                 verbose cd "$dir"
1558                 # texture: convert to jpeg and dds
1559                 # music: reduce bitrate
1560                 verbose export do_jpeg=false
1561                 verbose export do_jpeg_if_not_dds=true
1562                 verbose export jpeg_qual_rgb=80
1563                 verbose export jpeg_qual_a=99
1564                 verbose export do_dds=true
1565                 verbose export dds_flags=
1566                 verbose export do_ogg=true
1567                 verbose export ogg_qual=1
1568                 verbose export del_src=true
1569                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1570                 ;;
1571         release-buildpk3)
1572                 src=$1
1573                 dst=$2
1574                 transform=$3
1575                 case "$dst" in
1576                         /*)
1577                                 ;;
1578                         */)
1579                                 dst="$PWD/$dst"
1580                                 ;;
1581                 esac
1582                 verbose rm -rf Xonotic/temp
1583                 verbose mkdir -p Xonotic/temp
1584                 {
1585                         verbose cd "$src"
1586                         verbose git archive --format=tar HEAD
1587                 } | {
1588                         verbose cd Xonotic/temp
1589                         verbose tar xvf -
1590                 }
1591                 verbose cd Xonotic/temp
1592                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1593                         verbose cp ../source/progs.dat .
1594                         verbose cp ../source/csprogs.dat .
1595                         verbose cp ../source/menu.dat .
1596                         verbose rm -rf qcsrc
1597                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1598                         major=$(($gv / 10000))
1599                         minor=$(($gv / 100 - $major * 100))
1600                         patch=$(($gv - $major * 10000 - $minor * 100))
1601                         versionstr="$major.$minor.$patch"
1602                         case "$RELEASETYPE" in
1603                                 beta)
1604                                         versionstr="$versionstr""beta"
1605                                         ;;
1606                         esac
1607                         verbose sed -i "
1608                                 s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1609                                 s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1610                                 s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1611                         " defaultXonotic.cfg
1612                         (
1613                                 verbose cd gfx/menu/luminos
1614                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1615                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1616                                 verbose rm background_l2.svg
1617                         )
1618                 fi
1619                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1620                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1621                                 if [ -f "$X" ]; then
1622                                         verbose unzip "$X"
1623                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1624                                 fi
1625                         done
1626                 fi
1627                 verbose export git_src_repo="$d0/$src" # skip hash-object
1628                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1629                 verbose mkzip "../../$dst" *
1630                 verbose cd ../..
1631                 verbose rm -rf Xonotic/temp
1632                 ;;
1633         release-buildpk3s)
1634                 stamp=`cat Xonotic/stamp.txt`
1635                 src=$1
1636                 shift
1637                 dst=${src%.pk3dir}
1638                 case "$dst" in
1639                         data/xonotic-*)
1640                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1641                                 ;;
1642                         *)
1643                                 dst="$dst-$stamp"
1644                                 ;;
1645                 esac
1646                 while [ "$#" -gt 1 ]; do
1647                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1648                         shift
1649                         shift
1650                 done
1651                 ;;
1652         release-pack)
1653                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir             raw ''
1654                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1655                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1656                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                raw ''     low '-low'
1657                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir                       low ''
1658                 ;;
1659         release-pack-needsx11)
1660                 case "$DISPLAY" in
1661                         '')
1662                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1663                                 ;;
1664                         *)
1665                                 verbose "$SELF" release-pack
1666                                 ;;
1667                 esac
1668                 ;;
1669         release-zip)
1670                 stamp=`cat Xonotic/stamp.txt`
1671                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1672                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1673                 # let's pass crypto import laws of some nasty countries
1674                 crypto_libs=`find Xonotic -name \*d0_rijndael\*`
1675                 if [ -n "$crypto_libs" ]; then
1676                         verbose mkzip Xonotic-$stamp-crypto.zip \
1677                                 $crypto_libs
1678                         rm -f $crypto_libs
1679                 fi
1680                 # build the archives
1681                 verbose mkzip Xonotic-$stamp-engine.zip \
1682                         Xonotic/*.dll \
1683                         Xonotic/bin64/*.dll \
1684                         Xonotic/*.app \
1685                         Xonotic/xonotic-* \
1686                         Xonotic/xonotic.exe \
1687                         Xonotic/source/darkplaces/
1688                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1689                 verbose mkzip Xonotic-$stamp-common.zip \
1690                         Xonotic/source/fteqcc/ \
1691                         Xonotic/source/qcsrc/ \
1692                         Xonotic/Docs \
1693                         Xonotic/misc \
1694                         Xonotic/fteqcc \
1695                         Xonotic/server \
1696                         Xonotic/key_0.d0pk \
1697                         Xonotic/data/font-nimbussansl-$stamp.pk3
1698                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1699                 verbose mkzip0 Xonotic-$stamp.zip \
1700                         Xonotic/data/xonotic-$stamp-data.pk3 \
1701                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1702                         Xonotic/data/xonotic-$stamp-music.pk3 \
1703                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1704                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1705                 verbose mkzip0 Xonotic-$stamp-low.zip \
1706                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1707                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1708                         Xonotic/data/xonotic-$stamp-music-low.pk3
1709 #               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1710 #               verbose mkzip0 Xonotic-$stamp-high.zip \
1711 #                       Xonotic/data/xonotic-$stamp-data-raw.pk3 \
1712 #                       Xonotic/data/xonotic-$stamp-maps-raw.pk3 \
1713 #                       Xonotic/data/xonotic-$stamp-music.pk3 \
1714 #                       Xonotic/data/xonotic-$stamp-nexcompat.pk3
1715                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-lowdds.zip
1716                 verbose mkzip0 Xonotic-$stamp-lowdds.zip \
1717                         Xonotic/data/xonotic-$stamp-data-lowdds.pk3 \
1718                         Xonotic/data/xonotic-$stamp-maps-lowdds.pk3 \
1719                         Xonotic/data/xonotic-$stamp-music-low.pk3
1720                 ;;
1721         release)
1722                 verbose "$SELF" release-prepare
1723                 verbose "$SELF" release-maps
1724                 verbose "$SELF" release-engine
1725                 verbose "$SELF" release-qc
1726                 verbose "$SELF" release-pack-needsx11
1727                 verbose "$SELF" release-zip
1728                 ;;
1729
1730         *)
1731                 echo "Usage:"
1732                 echo "  $SELF admin-merge [<branch>]"
1733                 echo "  $SELF branch <branch>"
1734                 echo "  $SELF branch <remote> <branch> [<srcbranch>]"
1735                 echo "  $SELF branches"
1736                 echo "  $SELF checkout|switch <branch>"
1737                 echo "  $SELF checkout|switch <remote>/<branch>"
1738                 echo "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
1739                 echo "  $SELF clean --reclone"
1740                 echo "  $SELF compile [-c] [-r] [-0]"
1741                 echo "  $SELF each|foreach [-k] command..."
1742                 echo "  $SELF fix_upstream_rebase"
1743                 echo "  $SELF keygen"
1744                 echo "  $SELF merge"
1745                 echo "  $SELF push|commit [-s]"
1746                 echo "  $SELF release"
1747                 echo "  $SELF restore-patches"
1748                 echo "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
1749                 echo "  $SELF save-patches"
1750                 echo "  $SELF update-maps"
1751                 echo "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
1752                 ;;
1753 esac