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