]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
e5674a9e21e5894b3c5b792388124a6c7c0d35c2
[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
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                         enter "$d0/$d" verbose
1050                         base="`repobranch "$d"`"
1051                         reportecho "In $d:"
1052                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
1053                                 case "${ref#refs/remotes/origin/}" in
1054                                         "$base")
1055                                                 continue
1056                                                 ;;
1057                                         HEAD|master)
1058                                                 continue
1059                                                 ;;
1060                                         */*)
1061                                                 ;;
1062                                         *)
1063                                                 continue
1064                                                 ;;
1065                                 esac
1066                                 if [ -n "$branch" ]; then
1067                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1068                                                 continue
1069                                         fi
1070                                 fi
1071                                 case "$base" in
1072                                         master)
1073                                                 realbase=$base
1074                                                 ;;
1075                                         *)
1076                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1077                                                 l1=`git rev-list master.."$ref" | wc -l`
1078                                                 if [ $l0 -gt $l1 ]; then
1079                                                         realbase=master
1080                                                 else
1081                                                         realbase=$base
1082                                                 fi
1083                                                 ;;
1084                                 esac
1085                                 reportecho "  Branch $ref:"
1086                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1087                                 logdata=`git log --color "$realbase".."$ref"`
1088                                 if [ -z "$logdata" ]; then
1089                                         reportecho4 "--> not merging, no changes vs master"
1090                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1091                                                 git push origin :"${ref#refs/remotes/origin/}"
1092                                                 reportecho4 "--> branch deleted"
1093                                         fi
1094                                 else
1095                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1096                                         if [ -z "$diffdata" ]; then
1097                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1098                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ echo "$logdata"; } | less -r'; then
1099                                                         git push origin :"${ref#refs/remotes/origin/}"
1100                                                         reportecho4 "--> branch deleted"
1101                                                 fi
1102                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1103                                                 reportdo4 echo "$note"
1104                                                 reportecho4 "--> not merging, already had this one rejected before"
1105                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ echo "$logdata"; echo "$diffdata"; } | less -r'; then
1106                                                 git checkout "$realbase"
1107                                                 org=`git rev-parse HEAD`
1108                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1109                                                         git reset --hard "$org"
1110                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1111                                                         reportdo4 cat "$t"
1112                                                         reportecho4 "--> merge failed"
1113                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1114                                                         git reset --hard "$org"
1115                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1116                                                         reportdo4 cat "$t"
1117                                                         reportecho4 "--> compile failed"
1118                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1119                                                         git reset --hard "$org"
1120                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1121                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1122                                                         if [ x"$note" = x"del" ]; then
1123                                                                 git push origin :"${ref#refs/remotes/origin/}"
1124                                                                 reportecho4 "--> test failed, branch deleted"
1125                                                         elif [ -n "$note" ]; then
1126                                                                 reportdo4 echo "$note"
1127                                                                 reportecho4 "--> test failed"
1128                                                         else
1129                                                                 reportecho4 "--> test failed, postponed"
1130                                                         fi
1131                                                 else
1132                                                         echo "MERGING"
1133                                                         case ",`repoflags "$d"`," in
1134                                                                 *,svn,*)
1135                                                                         # we do quite a mess here... luckily we know $org
1136                                                                         git fetch # svn needs to be current
1137                                                                         git rebase -i --onto origin/master "$org"
1138                                                                         git svn dcommit --add-author-from
1139                                                                         git reset --hard "$org"
1140                                                                         ;;
1141                                                                 *)
1142                                                                         git push origin HEAD
1143                                                                         ;;
1144                                                         esac
1145                                                         reportecho4 "--> MERGED"
1146                                                         if yesno "Delete original branch \"$ref\"?"; then
1147                                                                 git push origin :"${ref#refs/remotes/origin/}"
1148                                                                 reportecho4 "--> branch deleted"
1149                                                         fi
1150                                                 fi
1151                                         else
1152                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1153                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1154                                                 if [ x"$note" = x"del" ]; then
1155                                                         git push origin :"${ref#refs/remotes/origin/}"
1156                                                         reportecho4 "--> branch deleted"
1157                                                 elif [ -n "$note" ]; then
1158                                                         reportdo4 echo "$note"
1159                                                         reportecho4 "--> rejected"
1160                                                 else
1161                                                         reportecho4 "--> postponed"
1162                                                 fi
1163                                         fi
1164                                 fi
1165                                 reportecho ""
1166                         done
1167                         reportecho ""
1168                 done
1169                 rm -f "$t"
1170                 echo "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1171                 ;;
1172         clean)
1173                 "$SELF" fix_config
1174                 "$SELF" update -N
1175                 force=false
1176                 gotoupstream=false
1177                 fetchupstream=false
1178                 gotomaster=false
1179                 rmuntracked=false
1180                 killbranches=false
1181                 # usage:
1182                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1183                 #   ./all clean --reclone
1184                 found=false
1185                 for X in "$@"; do
1186                         if [ x"$X" = x"--reclone" ]; then
1187                                 force=true
1188                                 fetchupstream=true
1189                                 gotoupstream=true
1190                                 gotomaster=true
1191                                 rmuntracked=true
1192                                 killbranches=true
1193                         elif [ x"$X" = x"-f" ]; then
1194                                 force=true
1195                         elif [ x"$X" = x"-u" ]; then
1196                                 gotoupstream=true
1197                         elif [ x"$X" = x"-U" ]; then
1198                                 gotoupstream=true
1199                                 fetchupstream=true
1200                         elif [ x"$X" = x"-fu" ]; then
1201                                 force=true
1202                                 gotoupstream=true
1203                         elif [ x"$X" = x"-fU" ]; then
1204                                 force=true
1205                                 gotoupstream=true
1206                                 fetchupstream=true
1207                         elif [ x"$X" = x"-m" ]; then
1208                                 gotomaster=true
1209                         elif [ x"$X" = x"-r" ]; then
1210                                 rmuntracked=true
1211                         elif [ x"$X" = x"-D" ]; then
1212                                 killbranches=true
1213                         else
1214                                 break
1215                         fi
1216                         found=true
1217                         shift
1218                 done
1219                 if ! $found; then
1220                         rmuntracked=true
1221                 fi
1222                 for d in $repos; do
1223                         verbose cd "$d0/$d"
1224                         if $gotoupstream; then
1225                                 if ! $force; then
1226                                         msg "Must also use -f (delete local changes) when using -u"
1227                                         exit 1
1228                                 fi
1229                                 if $gotomaster; then
1230                                         if $fetchupstream; then
1231                                                 verbose git fetch origin
1232                                                 verbose git remote prune origin
1233                                         fi
1234                                         verbose git checkout -f "`repobranch "$d"`"
1235                                         verbose git reset --hard origin/"`repobranch "$d"`"
1236                                 else
1237                                         r=`git symbolic-ref HEAD`
1238                                         r=${r#refs/heads/}
1239                                         rem=`git config "branch.$r.remote" || echo origin`
1240                                         bra=`git config "branch.$r.merge" || echo "$r"`
1241                                         upstream="$rem/${bra#refs/heads/}"
1242                                         if $fetchupstream; then
1243                                                 verbose git fetch "$rem"
1244                                                 verbose git remote prune "$rem"
1245                                         fi
1246                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1247                                                 upstream="origin/`repobranch "$d"`"
1248                                         fi
1249                                         verbose git reset --hard "$upstream"
1250                                 fi
1251                         elif $gotomaster; then
1252                                 if $force; then
1253                                         verbose git checkout -f "`repobranch "$d"`"
1254                                         verbose git reset --hard
1255                                 else
1256                                         verbose git checkout "`repobranch "$d"`"
1257                                 fi
1258                         elif $force; then
1259                                 verbose git reset --hard
1260                         fi
1261                         if $rmuntracked; then
1262                                 case "$d" in
1263                                         .)
1264                                                 verbose git clean -df
1265                                                 ;;
1266                                         *)
1267                                                 verbose git clean -xdf
1268                                                 ;;
1269                                 esac
1270                         fi
1271                         if $killbranches; then
1272                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1273                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1274                                                 verbose git branch -D "${B#refs/heads/}"
1275                                         fi
1276                                 done
1277                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch -t master origin/master || true
1278                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch -t "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1279                         fi
1280                         checkself "$cmd" "$@"
1281                 done
1282                 ;;
1283
1284         # release building goes here
1285         release-prepare)
1286                 #"$SELF" each git clean -fxd
1287                 case "$RELEASETYPE" in
1288                         beta)
1289                                 msg "Building a BETA"
1290                                 ;;
1291                         release)
1292                                 msg "Building a RELEASE"
1293                                 ;;
1294                         *)
1295                                 echo >&2 -n "$ESC[2J$ESC[H"
1296                                 msg ""
1297                                 msg ""
1298                                 msg ""
1299                                 msg ""
1300                                 msg ""
1301                                 msg ""
1302                                 msg "        +---------------------------------------------------------.---+"
1303                                 msg "        | NOTE                                                    | X |"
1304                                 msg "        +---------------------------------------------------------^---+"
1305                                 msg "        |   ____                                                      |"
1306                                 msg "        |  /    \  This is the official release build system.         |"
1307                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1308                                 msg "        | | STOP | you are not supposed to use this script and should |"
1309                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1310                                 msg "        |  \____/  and game code.                                     |"
1311                                 msg "        |                                                             |"
1312                                 msg "        |                      [ I understand ]                       |"
1313                                 msg "        +-------------------------------------------------------------+"
1314                                 sleep 10
1315                                 # A LOT of build infrastructure is required:
1316                                 # - vorbis-tools
1317                                 # - ImageMagick
1318                                 # - .ssh/config must be configured so the following
1319                                 #   host names are reachable and have a compile
1320                                 #   infrastructure set up:
1321                                 #   - xonotic-build-linux32 (with gcc on x86)
1322                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1323                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1324                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1325                                 #     and x86_64-w64-mingw32-g++)
1326                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1327                                 # - AMD Compressonator installed in WINE
1328                                 # - ResEdit installed in WINE
1329                                 # - a lot of other requirements you will figure out
1330                                 #   while reading the error messages
1331                                 # - environment variable RELEASETYPE set
1332                                 # - optionally, environment variable RELEASEDATE set
1333                                 #   (YYYYMMDD)
1334                                 exit 1
1335                                 ;;
1336                 esac
1337                 verbose rm -rf Xonotic Xonotic*.zip
1338                 verbose mkdir -p Xonotic
1339                 if [ -n "$RELEASEDATE" ]; then
1340                         verbose echo "$RELEASEDATE" > Xonotic/stamp.txt
1341                 else
1342                         verbose date +%Y%m%d > Xonotic/stamp.txt
1343                 fi
1344                 verbose git archive --format=tar HEAD -- Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk | {
1345                         verbose cd Xonotic
1346                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc
1347                         verbose tar xvf -
1348                         verbose rm -rf misc/builddeps
1349                         verbose mv misc/buildfiles/win32/* . || true
1350                         verbose mv misc/buildfiles/win64 bin64 || true
1351                         verbose mv misc/buildfiles/osx/* . || true
1352                         verbose rm -rf misc/buildfiles
1353                         verbose rm -rf misc/pki
1354                 }
1355                 {
1356                         verbose cd darkplaces
1357                         verbose git archive --format=tar HEAD
1358                 } | {
1359                         verbose cd Xonotic/source/darkplaces
1360                         verbose tar xvf -
1361                 }
1362                 {
1363                         verbose cd fteqcc
1364                         verbose git archive --format=tar HEAD
1365                 } | {
1366                         verbose cd Xonotic/source/fteqcc
1367                         verbose tar xvf -
1368                 }
1369                 {
1370                         verbose cd data/xonotic-data.pk3dir
1371                         verbose git archive --format=tar HEAD -- qcsrc Makefile
1372                 } | {
1373                         verbose cd Xonotic/source
1374                         verbose tar xvf -
1375                 }
1376                 rm -f Xonotic/key_15.d0pk
1377                 ;;
1378         release-compile-run)
1379                 host=$1
1380                 buildpath=$2
1381                 maketargets=$3
1382                 makeflags=$4
1383                 srcdir=$5
1384                 depsdir=$6
1385                 targetfiles=$7
1386                 set -x
1387                 if [ -n "$targetfiles" ]; then
1388                         case " $HOSTS_THAT_ARE_DISABLED " in
1389                                 *\ $host\ *)
1390                                         exit
1391                                         ;;
1392                         esac
1393                         case " $HOSTS_THAT_ARE_MYSELF " in
1394                                 *\ $host\ *)
1395                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1396                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1397                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1398                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1399                                         for f in $targetfiles; do
1400                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1401                                         done
1402                                         ;;
1403                                 *)
1404                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1405                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1406                                         verbose ssh "$host" "ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
1407                                         for f in $targetfiles; do
1408                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1409                                         done
1410                                         ;;
1411                         esac
1412                         # now rebrand the binaries...
1413                         for f in $targetfiles; do
1414                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1415                                 case "${f##*:}" in
1416                                         xonotic*.exe)
1417                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1418                                                 (
1419                                                         d=`mktemp -d -t rebrand.XXXXXX`
1420                                                         cd "$d"
1421                                                         echo "-mygames" > darkplaces.opt
1422                                                         zip -9r darkplaces.zip darkplaces.opt
1423                                                         cat darkplaces.zip
1424                                                         cd "$d0"
1425                                                         rm -rf "$d"
1426                                                 ) >> "${f##*:}"
1427                                                 ;;
1428                                 esac
1429                         done
1430                 fi
1431                 ;;
1432         release-compile)
1433                 suffix=$1
1434                 makeflags=$2
1435                 fteqcc_maketargets=$3
1436                 fteqcc_files=$4
1437                 darkplaces_maketargets=$5
1438                 darkplaces_files=$6
1439                 host=xonotic-build-$suffix
1440                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1441                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1442                 ;;
1443         release-engine-win32)
1444                 verbose "$SELF" release-compile win32 \
1445                         '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' \
1446                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1447                         '' ''
1448                 verbose "$SELF" release-compile win32 \
1449                         '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' \
1450                         '' '' \
1451                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1452                 ;;
1453         release-engine-win64)
1454                 verbose "$SELF" release-compile win64 \
1455                         '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' \
1456                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1457                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1458                 verbose "$SELF" release-compile win64 \
1459                         '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' \
1460                         '' '' \
1461                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1462                 ;;
1463         release-engine-osx)
1464                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1465                 verbose "$SELF" release-compile osx \
1466                         '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"' \
1467                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1468                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic-SDL.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1469                 verbose "$SELF" release-compile osx \
1470                         '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"' \
1471                         '' '' \
1472                         'cl-release' 'darkplaces-agl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-agl-bin'
1473                 ;;
1474         release-engine-linux32)
1475                 verbose "$SELF" release-compile linux32 \
1476                         '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' \
1477                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1478                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1479                 ;;
1480         release-engine-linux64)
1481                 verbose "$SELF" release-compile linux64 \
1482                         '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' \
1483                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1484                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1485                 ;;
1486         release-engine)
1487                 verbose "$SELF" release-engine-linux32 &
1488                 verbose "$SELF" release-engine-linux64 &
1489                 verbose "$SELF" release-engine-win32 &
1490                 verbose "$SELF" release-engine-win64 &
1491                 verbose "$SELF" release-engine-osx &
1492                 wait %1
1493                 wait %2
1494                 wait %3
1495                 wait %4
1496                 wait %5
1497                 wait
1498                 ;;
1499         release-maps)
1500                 verbose "$SELF" update-maps
1501                 ;;
1502         release-qc)
1503                 case "$RELEASETYPE" in
1504                         beta)
1505                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
1506                                 # back out of: source/qcsrc/server
1507                                 ;;
1508                         release)
1509                                 verbose make -C Xonotic/source FTEQCC="../../../fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 FTEQCCFLAGS_WATERMARK= clean all
1510                                 ;;
1511                 esac
1512                 verbose rm -f Xonotic/source/*/fteqcc.log
1513                 ;;
1514         release-buildpk3-transform-raw)
1515                 dir=$1
1516                 ;;
1517         release-buildpk3-transform-normal)
1518                 dir=$1
1519                 verbose cd "$dir"
1520                 # texture: convert to jpeg and dds
1521                 verbose export do_jpeg=true
1522                 verbose export jpeg_qual_rgb=95
1523                 verbose export jpeg_qual_a=99
1524                 verbose export do_dds=true
1525                 verbose export dds_flags=
1526                 verbose export do_ogg=false
1527                 verbose export del_src=true
1528                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1529                 ;;
1530         release-buildpk3-transform-low)
1531                 dir=$1
1532                 verbose cd "$dir"
1533                 # texture: convert to jpeg and dds
1534                 # music: reduce bitrate
1535                 verbose export do_jpeg=true
1536                 verbose export jpeg_qual_rgb=80
1537                 verbose export jpeg_qual_a=99
1538                 verbose export do_dds=false
1539                 verbose export do_ogg=true
1540                 verbose export ogg_qual=1
1541                 verbose export del_src=true
1542                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1543                 ;;
1544         release-buildpk3-transform-lowdds)
1545                 dir=$1
1546                 verbose cd "$dir"
1547                 # texture: convert to jpeg and dds
1548                 # music: reduce bitrate
1549                 verbose export do_jpeg=false
1550                 verbose export do_jpeg_if_not_dds=true
1551                 verbose export jpeg_qual_rgb=80
1552                 verbose export jpeg_qual_a=99
1553                 verbose export do_dds=true
1554                 verbose export dds_flags=
1555                 verbose export do_ogg=true
1556                 verbose export ogg_qual=1
1557                 verbose export del_src=true
1558                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1559                 ;;
1560         release-buildpk3)
1561                 src=$1
1562                 dst=$2
1563                 transform=$3
1564                 case "$dst" in
1565                         /*)
1566                                 ;;
1567                         */)
1568                                 dst="$PWD/$dst"
1569                                 ;;
1570                 esac
1571                 verbose rm -rf Xonotic/temp
1572                 verbose mkdir -p Xonotic/temp
1573                 {
1574                         verbose cd "$src"
1575                         verbose git archive --format=tar HEAD
1576                 } | {
1577                         verbose cd Xonotic/temp
1578                         verbose tar xvf -
1579                 }
1580                 verbose cd Xonotic/temp
1581                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1582                         verbose cp ../source/progs.dat .
1583                         verbose cp ../source/csprogs.dat .
1584                         verbose cp ../source/menu.dat .
1585                         verbose rm -rf qcsrc
1586                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1587                         major=$(($gv / 10000))
1588                         minor=$(($gv / 100 - $major * 100))
1589                         patch=$(($gv - $major * 10000 - $minor * 100))
1590                         versionstr="$major.$minor.$patch"
1591                         case "$RELEASETYPE" in
1592                                 beta)
1593                                         versionstr="$versionstr""beta"
1594                                         ;;
1595                         esac
1596                         verbose sed -i "
1597                                 s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1598                                 s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1599                                 s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1600                         " defaultXonotic.cfg
1601                         (
1602                                 verbose cd gfx/menu/luminos
1603                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1604                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1605                                 verbose rm background_l2.svg
1606                         )
1607                 fi
1608                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1609                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1610                                 if [ -f "$X" ]; then
1611                                         verbose unzip "$X"
1612                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1613                                 fi
1614                         done
1615                 fi
1616                 verbose export git_src_repo="$d0/$src" # skip hash-object
1617                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1618                 verbose mkzip "../../$dst" *
1619                 verbose cd ../..
1620                 verbose rm -rf Xonotic/temp
1621                 ;;
1622         release-buildpk3s)
1623                 stamp=`cat Xonotic/stamp.txt`
1624                 src=$1
1625                 shift
1626                 dst=${src%.pk3dir}
1627                 case "$dst" in
1628                         data/xonotic-*)
1629                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1630                                 ;;
1631                         *)
1632                                 dst="$dst-$stamp"
1633                                 ;;
1634                 esac
1635                 while [ "$#" -gt 1 ]; do
1636                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1637                         shift
1638                         shift
1639                 done
1640                 ;;
1641         release-pack)
1642                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir             raw ''
1643                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1644                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal ''            low '-low' lowdds '-lowdds'
1645                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                raw ''     low '-low'
1646                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir                       low ''
1647                 ;;
1648         release-pack-needsx11)
1649                 case "$DISPLAY" in
1650                         '')
1651                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
1652                                 ;;
1653                         *)
1654                                 verbose "$SELF" release-pack
1655                                 ;;
1656                 esac
1657                 ;;
1658         release-zip)
1659                 stamp=`cat Xonotic/stamp.txt`
1660                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
1661                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
1662                 # let's pass crypto import laws of some nasty countries
1663                 crypto_libs=`find Xonotic -name \*d0_rijndael\*`
1664                 if [ -n "$crypto_libs" ]; then
1665                         verbose mkzip Xonotic-$stamp-crypto.zip \
1666                                 $crypto_libs
1667                         rm -f $crypto_libs
1668                 fi
1669                 # build the archives
1670                 verbose mkzip Xonotic-$stamp-engine.zip \
1671                         Xonotic/*.dll \
1672                         Xonotic/bin64/*.dll \
1673                         Xonotic/*.app \
1674                         Xonotic/xonotic-* \
1675                         Xonotic/xonotic.exe \
1676                         Xonotic/source/darkplaces/
1677                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
1678                 verbose mkzip Xonotic-$stamp-common.zip \
1679                         Xonotic/source/fteqcc/ \
1680                         Xonotic/source/qcsrc/ \
1681                         Xonotic/Docs \
1682                         Xonotic/misc \
1683                         Xonotic/fteqcc \
1684                         Xonotic/server \
1685                         Xonotic/key_0.d0pk \
1686                         Xonotic/data/font-nimbussansl-$stamp.pk3
1687                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
1688                 verbose mkzip0 Xonotic-$stamp.zip \
1689                         Xonotic/data/xonotic-$stamp-data.pk3 \
1690                         Xonotic/data/xonotic-$stamp-maps.pk3 \
1691                         Xonotic/data/xonotic-$stamp-music.pk3 \
1692                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
1693                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
1694                 verbose mkzip0 Xonotic-$stamp-low.zip \
1695                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
1696                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
1697                         Xonotic/data/xonotic-$stamp-music-low.pk3
1698 #               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
1699 #               verbose mkzip0 Xonotic-$stamp-high.zip \
1700 #                       Xonotic/data/xonotic-$stamp-data-raw.pk3 \
1701 #                       Xonotic/data/xonotic-$stamp-maps-raw.pk3 \
1702 #                       Xonotic/data/xonotic-$stamp-music.pk3 \
1703 #                       Xonotic/data/xonotic-$stamp-nexcompat.pk3
1704                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-lowdds.zip
1705                 verbose mkzip0 Xonotic-$stamp-lowdds.zip \
1706                         Xonotic/data/xonotic-$stamp-data-lowdds.pk3 \
1707                         Xonotic/data/xonotic-$stamp-maps-lowdds.pk3 \
1708                         Xonotic/data/xonotic-$stamp-music-low.pk3
1709                 ;;
1710         release)
1711                 verbose "$SELF" release-prepare
1712                 verbose "$SELF" release-maps
1713                 verbose "$SELF" release-engine
1714                 verbose "$SELF" release-qc
1715                 verbose "$SELF" release-pack-needsx11
1716                 verbose "$SELF" release-zip
1717                 ;;
1718
1719         *)
1720                 echo "Usage:"
1721                 echo "  $SELF admin-merge [<branch>]"
1722                 echo "  $SELF branch <branch>"
1723                 echo "  $SELF branch <remote> <branch> [<srcbranch>]"
1724                 echo "  $SELF branches"
1725                 echo "  $SELF checkout|switch <branch>"
1726                 echo "  $SELF checkout|switch <remote>/<branch>"
1727                 echo "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
1728                 echo "  $SELF clean --reclone"
1729                 echo "  $SELF compile [-c] [-r] [-0]"
1730                 echo "  $SELF each|foreach [-k] command..."
1731                 echo "  $SELF fix_upstream_rebase"
1732                 echo "  $SELF keygen"
1733                 echo "  $SELF merge"
1734                 echo "  $SELF push|commit [-s]"
1735                 echo "  $SELF release"
1736                 echo "  $SELF restore-patches"
1737                 echo "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
1738                 echo "  $SELF save-patches"
1739                 echo "  $SELF update-maps"
1740                 echo "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
1741                 ;;
1742 esac