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