]> git.rm.cloudns.org Git - xonotic/xonotic.git/commitdiff
modularize ./all a lot
authorRudolf Polzer <divverent@xonotic.org>
Thu, 1 Mar 2012 13:09:29 +0000 (14:09 +0100)
committerRudolf Polzer <divverent@xonotic.org>
Thu, 1 Mar 2012 13:09:35 +0000 (14:09 +0100)
all
misc/tools/all/config.subr [new file with mode: 0644]
misc/tools/all/git.subr [new file with mode: 0644]
misc/tools/all/release.subr [new file with mode: 0644]
misc/tools/all/xonotic.subr [new file with mode: 0644]

diff --git a/all b/all
index a5f5d8ceb42e1918a89bf44a750f1ff07e781c8f..7d54d00cae2823eda957da69789660020f2d8dd8 100755 (executable)
--- a/all
+++ b/all
@@ -73,35 +73,6 @@ verbose()
        "$@"
 }
 
-visible_repo_name()
-{
-       case "$1" in
-               .)
-                       $ECHO "the root directory"
-                       ;;
-               *)
-                       $ECHO "\"$1\""
-                       ;;
-       esac
-}
-
-check_mergeconflict()
-{
-       if git ls-files -u | grep ' 1   '; then
-               $ECHO
-               $ECHO "MERGE CONFLICT."
-               $ECHO "change into the \"$1\" project directory, and then:"
-               $ECHO "- edit the files mentioned above with your favorite editor,"
-               $ECHO "  and fix the conflicts (marked with <<<<<<< blocks)"
-               $ECHO "- for binary files, you can select the files using"
-               $ECHO "  git checkout --ours or git checkout --theirs"
-               $ECHO "- when done with a file, 'git add' the file"
-               $ECHO "- when done, 'git commit'"
-               $ECHO
-               exit 1
-       fi
-}
-
 yesno()
 {
        yesno=
@@ -119,1989 +90,29 @@ yesno()
 enter()
 {
        $2 cd "$1" || exit 1
-       check_mergeconflict "$1"
-}
-
-repos_urls="
-.                             |                                                   | master         |
-data/xonotic-data.pk3dir      |                                                   | master         |
-data/xonotic-music.pk3dir     |                                                   | master         |
-data/xonotic-nexcompat.pk3dir |                                                   | master         | no
-darkplaces                    |                                                   | div0-stable    | svn
-netradiant                    |                                                   | master         |
-div0-gittools                 |                                                   | master         | no
-d0_blind_id                   |                                                   | master         |
-data/xonotic-maps.pk3dir      |                                                   | master         |
-mediasource                   |                                                   | master         | no
-fteqcc                        |                                                   | xonotic-stable | noautocrlf
-"
-# todo: in darkplaces, change repobranch to div0-stable
-
-repos=`$ECHO "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
-
-base=`git config remote.origin.url`
-case "$base" in
-       */xonotic.git)
-               base=${base%xonotic.git}
-               ;;
-       *)
-               $ECHO "The main repo is not xonotic.git, what have you done?"
-               exit 1
-               ;;
-esac
-pushbase=`git config remote.origin.pushurl || true`
-case "$pushbase" in
-       */xonotic.git)
-               pushbase=${pushbase%xonotic.git}
-               ;;
-       '')
-               ;;
-       *)
-               $ECHO "The main repo is not xonotic.git, what have you done?"
-               exit 1
-               ;;
-esac
-
-repourl()
-{
-       repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
-       if [ -n "$repo_t" ]; then
-               case "$repo_t" in
-                       *://*)
-                               $ECHO "$repo_t"
-                               ;;
-                       *)
-                               $ECHO "$base$repo_t"
-                               ;;
-               esac
-       else
-               if [ x"$1" = x"." ]; then
-                       $ECHO "$base""xonotic.git"
-               else
-                       $ECHO "$base${1##*/}.git"
-               fi
-       fi
-}
-
-repopushurl()
-{
-       [ -n "$pushbase" ] || return 0
-       repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
-       if [ -n "$repo_t" ]; then
-               case "$repo_t" in
-                       *://*)
-                               ;;
-                       *)
-                               $ECHO "$pushbase$repo_t"
-                               ;;
-               esac
-       else
-               if [ x"$1" = x"." ]; then
-                       $ECHO "$pushbase""xonotic.git"
-               else
-                       $ECHO "$pushbase${1##*/}.git"
-               fi
-       fi
-}
-
-repobranch()
-{
-       repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
-       if [ -n "$repo_t" ]; then
-               $ECHO "$repo_t"
-       else
-               $ECHO "master"
-       fi
-}
-
-repoflags()
-{
-       $ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 4 | tr -d ' '
-}
-
-listrepos()
-{
-       for d in $repos; do
-               p="${d%dir}"
-               f="`repoflags "$d"`"
-               # if we have .no file, skip
-               if [ -f "$d.no" ]; then
-                       msg "Repository $d disabled by a .no file, delete $d.no to enable"
-                       continue
-               fi
-               # if .yes file exists, always keep it
-               if [ -f "$d.yes" ]; then
-                       msg "Repository $d enabled by a .yes file"
-                       $ECHO "$d"
-                       continue
-               fi
-               # remove broken clones so they don't mess up stuff
-               if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
-                       msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
-                       verbose rm -rf "$d"
-                       continue
-               fi
-               # if we have the dir, always keep it
-               if [ -d "$d" ]; then
-                       msg "Repository $d enabled because it already exists"
-                       $ECHO "$d"
-                       continue
-               fi
-               # if we have matching pk3, skip
-               if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
-                       msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
-                       continue
-               fi
-               # if "no" flag is set, skip
-               case ",$f," in
-                       *,no,*)
-                               msg "Repository $d disabled by default, create $d.yes to enable"
-                               continue
-                               ;;
-               esac
-               # default: enable
-               msg "Repository $d enabled by default"
-               $ECHO "$d"
-       done
+       check_mergeconflict "$1" # defined in git.subr
 }
 
-repos=`listrepos`
-
 if [ "$#" = 0 ]; then
        set -- help
 fi
 cmd=$1
 shift
 
-case "$cmd" in
-       release|release-*)
-               export LC_ALL=C
-
-               release_args="$cmd $*"
-               msg "*** $release_args: start"
-               release_starttime=`date +%s`
-               release_end()
-               {
-                       release_endtime=`date +%s`
-                       release_deltatime=$(($release_endtime - $release_starttime))
-                       msg "*** $release_args: $release_deltatime seconds"
-               }
-               trap release_end EXIT
-               release_tempstarttime=$release_starttime
-               release_timereport()
-               {
-                       release_endtime=`date +%s` # RELEASE NOW!!!
-                       if [ -n "$*" ]; then
-                               release_deltatime=$(($release_endtime - $release_tempstarttime))
-                               msg "**** $release_args: $*: $release_deltatime seconds"
-                       fi
-                       release_tempstarttime=$release_endtime
-               }
-               release_git_extract_dir()
-               {
-                       release_src=$1; shift
-                       release_dst=$1; shift
-                       # try to create a hardlink
-                       if ln -f "$release_src/.git/HEAD" "$release_dst/.hardlink-test"; then
-                               rm -f "$release_dst/.hardlink-test"
-                               {
-                                       verbose cd "$release_src"
-                                       git ls-files HEAD -- "$@"
-                               } | {
-                                       while IFS= read -r F; do
-                                               case "$F" in */*) mkdir -p "$release_dst/${F%/*}" ;; esac
-                                               verbose ln -f "$release_src/$F" "$release_dst/$F"
-                                       done
-                               }
-                       else
-                               {
-                                       verbose cd "$release_src"
-                                       verbose git archive --format=tar HEAD -- "$@"
-                               } | {
-                                       verbose cd "$release_dst"
-                                       verbose tar xvf -
-                               }
-                       fi
-               }
-               ;;
-esac
-
-fix_upstream_rebase()
-{
-       if [ -z "$r_me" ] || [ -z "$r_other" ]; then
-               return
-       fi
-
-       # one of the two sides of the merge should be remote upstream, or all is fine
-       r_r=`git symbolic-ref HEAD`
-       r_r=${r_r#refs/heads/}
-       r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
-       r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
-       r_bra=${r_bra#refs/heads/}
-       if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
-               if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
-                       return
-               fi
-       fi
-
-       r_base=`git merge-base "$r_me" "$r_other"`
-
-       # no merge-base? upstream did filter-branch
-       if [ -n "$r_base" ]; then
-               # otherwise, check if the two histories are "similar"
-               r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
-               r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
-
-               # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
-               r_lc_me=`$ECHO "$r_l_me" | wc -l`
-               r_lc_other=`$ECHO "$r_l_other" | wc -l`
-               r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
-               r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
-
-               if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
-                       if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
-                               git reset --hard "$r_me"
-                               git pull --rebase
-                               return 1
-                       fi
-               fi
-       fi
-
-       return 0
-}
+# project config
+. "$d0/misc/tools/all/config.subr"
 
-fix_upstream_rebase_mergeok()
-{
-       r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
-       r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
-       fix_upstream_rebase
-}
+# shared commands
+handled=false
+. "$d0/misc/tools/all/git.subr" "$@"
 
-fix_upstream_rebase_mergefail()
-{
-       r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
-       r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
-       fix_upstream_rebase
-}
+# optional modules
+$handled || . "$d0/misc/tools/all/release.subr" "$@"
+$handled || . "$d0/misc/tools/all/xonotic.subr" "$@"
 
-fix_git_config()
-{
-       if ! [ -f ".git/config" ]; then
-               $ECHO "Not a git repository. Bailing out to not cause damage."
+if ! $handled; then
+       if [ x"$cmd" != x"help" ]; then
+               $ECHO "Run $SELF help for help."
                exit 1
        fi
-       verbose git config remote.origin.url "$1"
-       if [ -n "$2" ]; then
-               verbose git config remote.origin.pushurl "$2"
-       else
-               verbose git config --unset remote.origin.pushurl || true
-       fi
-       verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
-       case ",`repoflags "$d"`," in
-               *,noautocrlf,*)
-                       verbose git config --unset core.autocrlf || true
-                       ;;
-               *)
-                       verbose git config core.autocrlf input
-                       ;;
-       esac
-       if [ -z "`git config push.default || true`" ]; then
-               verbose git config push.default current # or is tracking better?
-       fi
-       verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
-       verbose git config filter.mapclean.smudge "cat"
-}
-
-mkzipr()
-{
-       archive=$1; shift
-       case "$RELEASETYPE" in
-               release)
-                       sevenzipflags=-mx=9
-                       zipflags=-9
-                       ;;
-               *)
-                       sevenzipflags=-mx=1
-                       zipflags=-1
-                       ;;
-       esac
-       find "$@" -exec touch -d "2001-01-01 01:01:01 +0000" {} \+ # ugly hack to make the pk3 files rsync-friendly
-       ziplist=`mktemp`
-       find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
-       7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
-       zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
-       rm -f "$ziplist"
-}
-
-mkzip()
-{
-       archive=$1; shift
-       case "$RELEASETYPE" in
-               release)
-                       sevenzipflags=-mx=9
-                       zipflags=-9
-                       ;;
-               *)
-                       sevenzipflags=-mx=1
-                       zipflags=-1
-                       ;;
-       esac
-       ziplist=`mktemp`
-       find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
-       7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
-       zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
-       rm -f "$ziplist"
-}
-
-mkzip0()
-{
-       archive=$1; shift
-       zip -0ry "$archive" "$@"
-}
-
-mirrorspeed()
-{
-       # first result is to be ignored, but we use it to check status
-       git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
-       { time -p git ls-remote "$1" refs/heads/master; } 2>&1 >/dev/null | head -n 1 | cut -d ' ' -f 2 | tr -d . | sed 's,^0*,,'
-               # unit: clock ticks (depends on what "time" returns
-}
-
-bestmirror()
-{
-       pre=$1; shift
-       suf=$1; shift
-
-       if ! { time -p true; } >/dev/null 2>&1; then
-               msg "Cannot do timing in this shell"
-               return 1
-       fi
-
-       bestin=
-       bestt=
-       for mir in "$@"; do
-               case "$mir" in
-                       *:*)
-                               in=${mir%%:*}
-                               op=${mir#*:}
-                               ;;
-                       *)
-                               in=$mir
-                               op=
-                               ;;
-               esac
-               m=$pre$in$suf
-               if t=`mirrorspeed "$m"`; then
-                       if [ -n "$t" ]; then
-                               tt=$(($t$op)) # fudge factor
-                               msg "$m -> $t$op = $tt ticks"
-                               if [ -z "$bestt" ] || [ "$tt" -lt "$bestt" ]; then
-                                       bestin=$in
-                                       bestt=$tt
-                               fi
-                       else
-                               msg "$m -> error"
-                       fi
-               else
-                       msg "$m -> FAIL"
-               fi
-       done
-       if [ -n "$bestin" ]; then
-               msg "Best mirror seems to be $pre$bestin$suf"
-               $ECHO "$bestin"
-       else
-               return 1
-       fi
-}
-
-case "$cmd" in
-       fix_upstream_rebase)
-               for d in $repos; do
-                       enter "$d0/$d" verbose
-                       verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
-               done
-               ;;
-       fix_config)
-               for d in $repos; do
-                       url=`repourl "$d"`
-                       pushurl=`repopushurl "$d"`
-                       branch=`repobranch "$d"`
-                       if [ -f "$d0/$d/.git/config" ]; then
-                               verbose cd "$d0/$d"
-                               fix_git_config "$url" "$pushurl"
-                               cd "$d0"
-                       fi
-               done
-               ;;
-       keygen)
-               # enable the ssh URL for pushing
-               "$SELF" update -N -p
-
-               if [ -f ~/.ssh/id_rsa.pub ]; then
-                       msg ""
-                       msg "A key already exists and no new one will be generated. If you"
-                       msg "already have done the procedure for getting your key approved, you"
-                       msg "can skip the following paragraph and already use the repository."
-                       msg ""
-                       msg "To get access, your key has to be approved first. For that, visit"
-                       msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
-                       msg "the \"Support\" tracker in the \"Repository\" category where you"
-                       msg "apply for access and paste the following output into the issue:"
-                       msg ""
-                       msg "`cat ~/.ssh/id_rsa.pub`"
-                       msg ""
-                       msg "Note that you will only have write access to branches that start"
-                       msg "with your user name."
-               elif [ -f ~/.ssh/id_dsa.pub ]; then
-                       msg ""
-                       msg "A key already exists and no new one will be generated. If you"
-                       msg "already have done the procedure for getting your key approved, you"
-                       msg "can skip the following paragraph and already use the repository."
-                       msg ""
-                       msg "To get access, your key has to be approved first. For that, visit"
-                       msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
-                       msg "the \"Support\" tracker in the \"Repository\" category where you"
-                       msg "apply for access and paste the following output into the issue:"
-                       msg ""
-                       msg "`cat ~/.ssh/id_dsa.pub`"
-                       msg ""
-                       msg "Note that you will only have write access to branches that start"
-                       msg "with your user name."
-               else
-                       msg ""
-                       msg "No key has been generated yet. One will be generated now."
-                       msg "If other people are using your computer, it is recommended"
-                       msg "to specify a passphrase. Otherwise you can simply hit ENTER"
-                       msg "when asked for a passphrase."
-                       msg ""
-                       ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
-                       msg ""
-                       msg "To get access, your key has to be approved first. For that, visit"
-                       msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
-                       msg "the \"Support\" tracker in the \"Repository\" category where you"
-                       msg "apply for access and paste the following output into the issue:"
-                       msg ""
-                       msg "`cat ~/.ssh/id_rsa.pub`"
-                       msg ""
-                       msg "Note that you will only have write access to branches that start"
-                       msg "with your user name."
-               fi
-               ;;
-       update|pull)
-               allow_pull=true
-               location=current
-               oldbase=$base
-               oldpushbase=$pushbase
-               # transition old URLs
-               if [ x"$base" = x"ssh://xonotic@git.xonotic.org/" ]; then
-                       base=ssh://xonotic@push.git.xonotic.org/
-               fi
-               if [ x"$pushbase" = x"ssh://xonotic@git.xonotic.org/" ]; then
-                       pushbase=ssh://xonotic@push.git.xonotic.org/
-               fi
-               while :; do
-                       if [ x"$1" = x"-N" ]; then
-                               allow_pull=false
-                       elif [ x"$1" = x"-p" ]; then
-                               pushbase=ssh://xonotic@push.git.xonotic.org/
-                       elif [ x"$1" = x"-ps" ]; then
-                               pushbase=ssh://xonotic@push.git.xonotic.org/
-                       elif [ x"$1" = x"-ph" ]; then
-                               pushbase=http://push.git.xonotic.org/login/xonotic/
-                       elif [ x"$1" = x"-s" ]; then
-                               base=ssh://xonotic@push.git.xonotic.org/
-                       elif [ x"$1" = x"-g" ]; then
-                               base=git://git.xonotic.org/xonotic/
-                               location=best
-                       elif [ x"$1" = x"-h" ]; then
-                               base=http://git.xonotic.org/xonotic/
-                               location=best
-                       elif [ x"$1" = x"-l" ]; then
-                               case "$2" in
-                                       nl) ;;
-                                       de) ;;
-                                       us) ;;
-                                       best) ;;
-                                       default) ;;
-                                       *)
-                                               msg "Invalid location!"
-                                               msg "Possible locations for the -l option:"
-                                               msg "  nl (Netherlands, run by merlijn)"
-                                               msg "  de (Germany, run by divVerent)"
-                                               msg "  us (United States of America, run by detrate)"
-                                               msg "  best (find automatically)"
-                                               msg "  default (currently nl)"
-                                               exit 1
-                                               ;;
-                               esac
-                               location=$2
-                               shift
-                       else
-                               break
-                       fi
-                       shift
-               done
-               case "$location" in
-                       current)
-                               if [ x"`git config xonotic.all.mirrorselection 2>/dev/null || true`" != x"done" ]; then
-                                       location=best
-                               fi
-                               ;;
-               esac
-               case "$location" in
-                       best)
-                               # if we fetched via ssh://, switch to git:// for fetching and keep using ssh:// for pushing
-                               case "$base" in
-                                       ssh://*|*/login/*)
-                                               pushbase=$base
-                                               base=git://git.xonotic.org/xonotic/
-                                               ;;
-                               esac
-                               newbase=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,:// .git.xonotic.org/,"`
-                               case "$newbase" in
-                                       *\ *)
-                                               if location=`bestmirror $newbase"xonotic.git" de us nl:'*6/5'`; then # 20% malus to the NL server to not overload it too much
-                                                       git config xonotic.all.mirrorselection done
-                                               else
-                                                       location=current
-                                               fi
-                                               ;;
-                                       *)
-                                               location=current
-                                               ;;
-                               esac
-                               ;;
-               esac
-               case "$location" in
-                       default)
-                               location=
-                               ;;
-                       current)
-                               case "$base" in
-                                       *://*.git.xonotic.org/*)
-                                               location=${base%%.git.xonotic.org/*}
-                                               location=${location##*://}
-                                               ;;
-                                       *)
-                                               location=
-                                               ;;
-                               esac
-                               ;;
-               esac
-               if [ -n "$location" ]; then
-                       base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
-               else
-                       base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
-               fi
-               pushbase=`$ECHO "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://xonotic@push.git.xonotic.org/,"`
-               if [ x"$base" != x"$oldbase" ] || [ x"$pushbase" != x"$oldpushbase" ]; then
-                       url=`repourl .`
-                       pushurl=`repopushurl .`
-                       fix_git_config "$url" "$pushurl"
-                       "$SELF" fix_config
-               elif $allow_pull; then
-                       "$SELF" fix_config
-               fi
-               for d in $repos; do
-                       url=`repourl "$d"`
-                       pushurl=`repopushurl "$d"`
-                       branch=`repobranch "$d"`
-                       if [ -f "$d0/$d/.git/config" ]; then
-                               # if we have .no file, skip
-                               if [ -f "$d0/$d.no" ]; then
-                                       msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
-                                       continue
-                               fi
-                               if $allow_pull; then
-                                       enter "$d0/$d" verbose
-                                       r=`git symbolic-ref HEAD`
-                                       r=${r#refs/heads/}
-                                       if git config branch.$r.remote >/dev/null 2>&1; then
-                                               if ! verbose git pull; then
-                                                       fix_upstream_rebase_mergefail || true
-                                                       check_mergeconflict "$d"
-                                                       $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
-                                                       read -r DUMMY
-                                               else
-                                                       fix_upstream_rebase_mergeok || true
-                                               fi
-                                       fi
-
-                                       cd "$d00"
-                                       checkself "$cmd" "$@"
-                                       cd "$d0/$d"
-                                       verbose git remote prune origin
-                                       cd "$d0"
-                               fi
-                       else
-                               if [ -d "$d0/$d" ]; then
-                                       if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
-                                               verbose rm -rf "$d0/$d"
-                                       else
-                                               echo "Note: $d0/$d will stay broken."
-                                               continue
-                                       fi
-                               fi
-                               verbose git clone "$url" "$d0/$d"
-                               enter "$d0/$d" verbose
-                               fix_git_config "$url" "$pushurl"
-                               if [ "$branch" != "master" ]; then
-                                       verbose git checkout --track -b "$branch" origin/"$branch"
-                               fi
-                               cd "$d0"
-                       fi
-               done
-               ;;
-       update-maps)
-               misc/tools/xonotic-map-compiler-autobuild download
-               ;;
-       checkout|switch)
-               checkoutflags=
-               if [ x"$1" = x"-f" ]; then
-                       checkoutflags=-f
-                       shift
-               fi
-               remote=$1
-               branch=$2
-               if [ -z "$branch" ]; then
-                       case "$remote" in
-                               origin/*)
-                                       branch=${remote#origin/}
-                                       remote=origin
-                                       ;;
-                               *)
-                                       branch=$remote
-                                       remote=origin
-                                       ;;
-                       esac
-               fi
-               if [ -n "$checkoutflags" ]; then
-                       set -- -f "$@" # to make checkself work again
-               fi
-               exists=false
-               for d in $repos; do
-                       enter "$d0/$d" verbose
-                       b=$branch
-                       if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
-                               exists=true
-                               verbose git checkout $checkoutflags "$b"
-                       elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
-                               exists=true
-                               verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
-                       else
-                               b=`repobranch "$d"`
-                               if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
-                                       verbose git checkout $checkoutflags "$b"
-                               elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
-                                       verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
-                               else
-                                       $ECHO "WTF? Not even branch $b doesn't exist in $d"
-                                       exit 1
-                               fi
-                       fi
-                       cd "$d00"
-                       checkself "$cmd" "$@"
-                       cd "$d0"
-               done
-               if ! $exists; then
-                       $ECHO "The requested branch was not found in any repository."
-               fi
-               exec "$SELF" branch
-               ;;
-       branch)
-               remote=$1
-               branch=$2
-               srcbranch=$3
-               if [ -z "$branch" ]; then
-                       branch=$remote
-                       remote=origin
-               fi
-               if [ -z "$branch" ]; then
-                       for d in $repos; do
-                               enter "$d0/$d"
-                               r=`git symbolic-ref HEAD`
-                               r=${r#refs/heads/}
-                               $ECHO "$d is at $r"
-                               cd "$d0"
-                       done
-               else
-                       for d in $repos; do
-                               dv=`visible_repo_name "$d"`
-                               enter "$d0/$d" verbose
-                               if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
-                                       $ECHO "Already having this branch in $dv."
-                               else
-                                       if yesno "Branch in $dv?"; then
-                                               if [ -n "$srcbranch" ]; then
-                                                       b=$srcbranch
-                                               else
-                                                       b=origin/"`repobranch "$d"`"
-                                                       verbose git fetch origin || true
-                                               fi
-                                               # TODO do this without pushing
-                                               verbose git checkout -b "$branch" "$b"
-                                               verbose git config "branch.$branch.remote" "$remote"
-                                               verbose git config "branch.$branch.merge" "refs/heads/$branch"
-                                       fi
-                               fi
-                               cd "$d0"
-                       done
-                       "$SELF" branch
-               fi
-               ;;
-       branches)
-               for d in $repos; do
-                       cd "$d0/$d" # am in a pipe, shouldn't use enter
-                       git branch -r -v -v | cut -c 3- | sed "s/^(no branch)/(no_branch)/" | sed "s,^,$d ,"
-                       cd "$d0"
-               done | {
-                       branches_list=
-                       # branches_repos_*=
-                       while read -r d BRANCH REV TEXT; do
-                               if [ x"$BRANCH" = x"`repobranch "$d"`" ]; then
-                                       continue
-                               fi
-                               if [ x"$REV" = x"->" ]; then
-                                       continue
-                               fi
-                               BRANCH=${BRANCH#remotes/}
-                               ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
-                               branches_list="$branches_list $BRANCH" # TEH SORT MAKEZ IT UNIEQ
-                               eval "r=\$branches_repos_$ID"
-                               r="$r $d"
-                               eval "branches_repos_$ID=\$r"
-                       done
-                       $ECHO -n "$branches_list" | xargs -n 1 $ECHO | sort -u | while IFS= read -r BRANCH; do
-                               ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
-                               eval "r=\$branches_repos_$ID"
-                               printf "%-60s %s\n" "$BRANCH" "$r"
-                               #$ECHO "$BRANCH: $r"
-                       done
-               }
-               ;;
-       merge)
-               for d in $repos; do
-                       dv=`visible_repo_name "$d"`
-                       enter "$d0/$d" verbose
-                       r=`git symbolic-ref HEAD`
-                       r=${r#refs/heads/}
-                       if git log HEAD..origin/"`repobranch "$d"`" | grep .; then
-                               # we have uncommitted changes
-                               if yesno "Could merge from \"`repobranch "$d"`\" into \"$r\" in $dv. Do it?"; then
-                                       if ! verbose git merge origin/"`repobranch "$d"`"; then
-                                               check_mergeconflict "$d"
-                                               exit 1 # this should ALWAYS be fatal
-                                       fi
-                               fi
-                       fi
-                       cd "$d0"
-               done
-               ;;
-       push|commit)
-               submit=$1
-               for d in $repos; do
-                       dv=`visible_repo_name "$d"`
-                       enter "$d0/$d" verbose
-                       r=`git symbolic-ref HEAD`
-                       r=${r#refs/heads/}
-                       diffdata=`git diff --color HEAD`
-                       if [ -n "$diffdata" ]; then
-                               # we have uncommitted changes
-                               if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
-                                       verbose git commit -a
-                               fi
-                       fi
-                       rem=`git config "branch.$r.remote" || $ECHO origin`
-                       bra=`git config "branch.$r.merge" || $ECHO "$r"`
-                       upstream="$rem/${bra#refs/heads/}"
-                       if ! git rev-parse "$upstream" >/dev/null 2>&1; then
-                               upstream="origin/`repobranch "$d"`"
-                       fi
-                       logdata=`git log --color "$upstream".."$r"`
-                       if [ -n "$logdata" ]; then
-                               if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
-                                       verbose git push "$rem" HEAD
-                               fi
-                       fi
-                       if [ x"$submit" = x"-s" ]; then
-                               case "$r" in
-                                       */*)
-                                               verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
-                                               ;;
-                               esac
-                       fi
-                       cd "$d0"
-               done
-               ;;
-       compile)
-               cleand0=false
-               cleandp=false
-               cleanqcc=false
-               cleanqc=false
-               compiled0=false
-               debug=debug
-               snowleopardhack=false
-               if [ -z "$CC" ]; then
-                       export CC="gcc"
-               fi
-               export CC="$CC -DSUPPORTIPV6"
-               while :; do
-                       case "$1" in
-                               -0)
-                                       compiled0=true
-                                       shift
-                                       ;;
-                               -c)
-                                       cleand0=true
-                                       cleandp=true
-                                       cleanqcc=true
-                                       cleanqc=true
-                                       shift
-                                       ;;
-                               -r|-p)
-                                       case "$1" in
-                                               -p)
-                                                       debug=profile
-                                                       ;;
-                                               -r)
-                                                       debug=release
-                                                       ;;
-                                       esac
-                                       export CC="$CC -g"
-                                       case "`$CC -dumpversion`" in
-                                               [5-9]*|[1-9][0-9]*|4.[3-9]*|4.[1-9][0-9]*)
-                                                       # gcc 4.3 or higher
-                                                       # -march=native is broken < 4.3
-                                                       if $CC -mtune=native -march=native misc/tools/conftest.c -o conftest >/dev/null 2>&1; then
-                                                               export CC="$CC -mtune=native -march=native"
-                                                       fi
-                                                       ;;
-                                       esac
-                                       if [ -n "$WE_HATE_OUR_USERS" ]; then
-                                               export CC="$CC -fno-common"
-                                       fi
-                                       shift
-                                       ;;
-                               *)
-                                       break
-                                       ;;
-                       esac
-               done
-               if [ -n "$WE_HATE_OUR_USERS" ]; then
-                       TARGETS="sv-$debug cl-$debug"
-               elif [ x"`uname`" = x"Darwin" ]; then
-                       case "`uname -r`" in
-                               ?.*)
-                                       TARGETS="sv-$debug cl-$debug sdl-$debug"
-                                       ;;
-                               *)
-                                       # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
-                                       snowleopardhack=true
-                                       TARGETS="sv-$debug sdl-$debug"
-                                       ;;
-                       esac
-                       export CC="$CC -fno-reorder-blocks -I$PWD/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks/SDL.framework/Headers -F$PWD/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
-               else
-                       TARGETS="sv-$debug cl-$debug sdl-$debug"
-               fi
-               if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
-                       # if we give the command make the arg "", it will surely fail (invalid filename),
-                       # so better handle it as an empty client option
-                       BAD_TARGETS=" "
-                       shift
-               elif [ -n "$1" ]; then
-                       BAD_TARGETS=
-                       TARGETS_SAVE=$TARGETS
-                       TARGETS=
-                       for X in $1; do
-                               case "$X" in
-                                       sdl)
-                                               TARGETS="$TARGETS sdl-debug"
-                                               ;;
-                                       agl)
-                                               TARGETS="$TARGETS cl-debug"
-                                               if $snowleopardhack; then
-                                                       export CC="$CC -arch i386"
-                                               fi
-                                               ;;
-                                       glx|wgl)
-                                               TARGETS="$TARGETS cl-debug"
-                                               ;;
-                                       dedicated)
-                                               TARGETS="$TARGETS sv-debug"
-                                               ;;
-                                       *)
-                                               BAD_TARGETS="$BAD_TARGETS $X"
-                                               ;;
-                               esac
-                       done
-                       if [ -n "$TARGETS" ]; then # at least a valid client
-                               shift
-                       else # no valid client, let's assume this option is not meant to be a client then
-                               TARGETS=$TARGETS_SAVE
-                               BAD_TARGETS=
-                       fi
-               fi
-               if [ -z "$MAKEFLAGS" ]; then
-                       if [ -f /proc/cpuinfo ]; then
-                               ncpus=$((`grep -c '^processor   :' /proc/cpuinfo || true`+0))
-                               if [ $ncpus -gt 1 ]; then
-                                       MAKEFLAGS=-j$ncpus
-                               fi
-                       fi
-                       if [ -n "$WE_HATE_OUR_USERS" ]; then
-                               MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
-                       fi
-               fi
-
-               
-               if ! verbose $CC misc/tools/conftest.c -o conftest; then
-                       msg ""
-                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
-                       msg "~~~~~~~~~~ COMPILER ~~~~~~~~~~"
-                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
-                       msg "~~~~~~~~~~~~~~_...._~~~~~~~~~~"
-                       msg "~~~~~~~~~~~,-'     \\\`-._~~~~~~"
-                       msg "~~~~~~~~~~/     --. ><  \\~~~~~"
-                       msg "~~~~~~~~~/      (*)> -<: \\~~~~"
-                       msg "~~~~~~~~~(     ^~-'  (*) )~~~~"
-                       msg "~~~~~~~~~\\        ^+-_/  |~~~~"
-                       msg "~~~~~~~~~~\\       {vvv}  |~~~~"
-                       msg "~~~~~~~~~~,\\    , {^^^},/~~~~~"
-                       msg "~~~~~~~~,/  \`---.....-'~~W~~~~"
-                       msg "~~~~~~,/   \\_____/_\\_W~~/~~~~~"
-                       msg "~~~~~/          /~~~\\__/~~~~~~"
-                       msg "~~~~/          /~~~~~~~~~~~~~~"
-                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
-                       msg "~~~~~~~ Y U NO COMPILE ~~~~~~~"
-                       msg "~~~~~~~~~~~~ CODE ~~~~~~~~~~~~"
-                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
-                       msg ""
-                       exit 1
-               fi
-               rm -f conftest
-
-               verbose cd "$d0/d0_blind_id"
-               if ! $compiled0; then
-                       # compilation of crypto library failed
-                       # use binaries then, if we can...
-                       mkdir -p .libs
-                       if [ -n "$WE_HATE_OUR_USERS" ]; then
-                               verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
-                               verbose cp "$d0/misc/buildfiles/win32/libd0_rijndael"-* .libs/
-                               verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
-                       else
-                               case "`uname`" in
-                                       Linux)
-                                               case `uname -m` in
-                                                       x86_64)
-                                                               #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
-                                                               #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_rijndael".* .libs/
-                                                               #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
-                                                               MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
-                                                               ;;
-                                                       *86)
-                                                               #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
-                                                               #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_rijndael".* .libs/
-                                                               #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
-                                                               MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
-                                                               ;;
-                                                       *)
-                                                               compiled0=true
-                                                               ;;
-                                               esac
-                                               ;;
-                                       Darwin)
-                                               verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
-                                               verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael".* .libs/
-                                               ;;
-                                       *)
-                                               compiled0=true
-                                               ;;
-                               esac
-                       fi
-               fi
-               if $compiled0; then
-                       if $cleand0; then
-                               if [ -f Makefile ]; then
-                                       verbose make $MAKEFLAGS distclean
-                               fi
-                       fi
-                       if ! [ -f Makefile ]; then
-                               verbose sh autogen.sh
-                               verbose ./configure
-                       fi
-                       verbose make $MAKEFLAGS
-               fi
-
-               verbose cd "$d0/fteqcc"
-               if $cleanqcc; then
-                       verbose make $MAKEFLAGS clean
-               fi
-               verbose make $MAKEFLAGS
-
-               verbose cd "$d0/data/xonotic-data.pk3dir"
-               if $cleanqc; then
-                       verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
-               fi
-               verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
-               # 4 levels up: data, xonotic-data, qcsrc, server
-
-               verbose cd "$d0/darkplaces"
-               if [ x"$BAD_TARGETS" = x" " ]; then
-                       $ECHO "Warning: invalid empty client, default clients will be used."
-               fi
-               if $cleandp; then
-                       verbose make $MAKEFLAGS clean
-               fi
-               for T in $TARGETS; do
-                       verbose make $MAKEFLAGS STRIP=: "$@" "$T"
-               done
-               for T in $BAD_TARGETS; do
-                       $ECHO "Warning: discarded invalid client $T."
-               done
-
-               verbose "$SELF" update-maps
-               ;;
-       run)
-               if [ -n "$WE_HATE_OUR_USERS" ]; then
-                       client=
-                       export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
-               elif [ x"`uname`" = x"Darwin" ]; then
-                       export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS:$d0/d0_blind_id/.libs"
-                       export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
-                       client=-sdl
-               else
-                       export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
-                       client=-sdl
-               fi
-               case "$1" in
-                       sdl|glx|agl|dedicated)
-                               client=-$1
-                               shift
-                               ;;
-                       wgl)
-                               client=
-                               shift
-                               ;;
-               esac
-               if ! [ -x "darkplaces/darkplaces$client" ]; then
-                       if [ -x "darkplaces/darkplaces$client.exe" ]; then
-                               client=$client.exe
-                       else
-                               $ECHO "Client darkplaces/darkplaces$client not found, aborting"
-                               exit 1
-                       fi
-               fi
-               set -- "darkplaces/darkplaces$client" -xonotic "$@"
-
-               # if pulseaudio is running: USE IT
-               if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
-                       if ps -C pulseaudio >/dev/null; then
-                               if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
-                                       export SDL_AUDIODRIVER=pulse
-                               fi
-                       fi
-               fi
-
-               binary=$1
-
-               if [ x"$USE_GDB" = x"yes" ]; then
-                       set -- gdb --args "$@"
-               elif [ x"$USE_GDB" = x"core" ] && which gdb >/dev/null 2>&1; then
-                       set -- gdb --batch -x savecore.gdb --args "$@"
-               elif which catchsegv >/dev/null 2>&1; then
-                       set -- catchsegv "$@"
-               fi
-               rm -f xonotic.core
-               "$@" || true
-               if [ -f xonotic.core ]; then
-                       if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
-                               gdb "$binary" xonotic.core
-                       #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
-                       #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
-                       #       # somehow send it
-                       #       rm -f xonotic.core.tar.gz
-                       else
-                               $ECHO "The core dump can be examined later by"
-                               $ECHO "  gdb $binary xonotic.core"
-                       fi
-                       exit 1
-               fi
-               ;;
-       each|foreach)
-               keep_going=false
-               if [ x"$1" = x"-k" ]; then
-                       keep_going=true
-                       shift
-               fi
-               for d in $repos; do
-                       if verbose cd "$d0/$d"; then
-                               if $keep_going; then
-                                       verbose "$@" || true
-                               else
-                                       verbose "$@"
-                               fi
-                               cd "$d0"
-                       fi
-               done
-               ;;
-       save-patches)
-               outfile=$1
-               patchdir=`mktemp -d -t save-patches.XXXXXX`
-               for d in $repos; do
-                       enter "$d0/$d" verbose
-                       git branch -v -v | cut -c 3- | {
-                               i=0
-                               while read -r BRANCH REV UPSTREAM TEXT; do
-                                       case "$UPSTREAM" in
-                                               \[*)
-                                                       UPSTREAM=${UPSTREAM#\[}
-                                                       UPSTREAM=${UPSTREAM%\]}
-                                                       UPSTREAM=${UPSTREAM%:*}
-                                                       TRACK=true
-                                                       ;;
-                                               *)
-                                                       UPSTREAM=origin/"`repobranch "$d"`"
-                                                       TRACK=false
-                                                       ;;
-                                       esac
-                                       if [ x"$REV" = x"->" ]; then
-                                               continue
-                                       fi
-                                       if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
-                                               $ECHO "$d" > "$patchdir/$i/info.txt"
-                                               $ECHO "$BRANCH" >> "$patchdir/$i/info.txt"
-                                               $ECHO "$UPSTREAM" >> "$patchdir/$i/info.txt"
-                                               $ECHO "$TRACK" >> "$patchdir/$i/info.txt"
-                                               i=$(($i+1))
-                                       else
-                                               rm -rf "$patchdir/$i"
-                                       fi
-                               done
-                       }
-               done
-               ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
-               rm -rf "$patchdir"
-               ;;
-       restore-patches)
-               infile=$1
-               patchdir=`mktemp -d -t restore-patches.XXXXXX`
-               ( cd "$patchdir" && tar xvzf - ) < "$infile"
-               # detach the head
-               for P in "$patchdir"/*/info.txt; do
-                       D=${P%/info.txt}
-                       exec 3<"$P"
-                       read -r d <&3
-                       read -r BRANCH <&3
-                       read -r UPSTREAM <&3
-                       read -r TRACK <&3
-                       verbose git checkout HEAD^0
-                       verbose git branch -D "$BRANCH"
-                       if [ x"$TRACK" = x"true" ]; then
-                               verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
-                       else
-                               verbose git branch -b "$BRANCH" "$UPSTREAM"
-                       fi
-                       verbose git am "$D"
-               done
-               rm -rf "$patchdir"
-               ;;
-       admin-merge)
-               branch=$1
-               only_delete=false
-               case "$branch" in
-                       -d)
-                               branch=
-                               only_delete=true
-                               ;;
-               esac
-               t=`mktemp`
-               report=""
-               reportecho()
-               {
-                       report=$report"$*$LF"
-                       $ECHO "$*"
-               }
-               reportecho4()
-               {
-                       report=$report"    $*$LF"
-                       $ECHO "    $*"
-               }
-               reportdo4()
-               {
-                       o=`"$@" | sed 's/^/    /' || true`
-                       reportecho "$o"
-               }
-               for d in $repos; do
-                       case "$d" in
-                               fteqcc)
-                                       # sorry, fteqcc repo is managed manually
-                                       continue
-                                       ;;
-                       esac
-                       enter "$d0/$d" verbose
-                       base="`repobranch "$d"`"
-                       reportecho "In $d:"
-                       for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
-                               case "${ref#refs/remotes/origin/}" in
-                                       "$base")
-                                               continue
-                                               ;;
-                                       HEAD|master)
-                                               continue
-                                               ;;
-                                       */*)
-                                               ;;
-                                       *)
-                                               continue
-                                               ;;
-                               esac
-                               if [ -n "$branch" ]; then
-                                       if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
-                                               continue
-                                       fi
-                               fi
-                               case "$base" in
-                                       master)
-                                               realbase=$base
-                                               ;;
-                                       *)
-                                               l0=`git rev-list "$base".."$ref" | wc -l`
-                                               l1=`git rev-list master.."$ref" | wc -l`
-                                               if [ $l0 -gt $l1 ]; then
-                                                       realbase=master
-                                               else
-                                                       realbase=$base
-                                               fi
-                                               ;;
-                               esac
-                               reportecho "  Branch $ref:"
-                               note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
-                               logdata=`git log --color "$realbase".."$ref"`
-                               if [ -z "$logdata" ]; then
-                                       reportecho4 "--> not merging, no changes vs master"
-                                       if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
-                                               git push origin :"${ref#refs/remotes/origin/}"
-                                               reportecho4 "--> branch deleted"
-                                       fi
-                               else
-                                       diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
-                                       if [ -z "$diffdata" ]; then
-                                               reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
-                                               if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ $ECHO "$logdata"; } | less -r'; then
-                                                       git push origin :"${ref#refs/remotes/origin/}"
-                                                       reportecho4 "--> branch deleted"
-                                               fi
-                                       elif $only_delete; then
-                                               reportecho4 "--> skipped in delete-only run"
-                                       elif [ -z "$branch" ] && [ -n "$note" ]; then
-                                               reportdo4 $ECHO "$note"
-                                               reportecho4 "--> not merging, already had this one rejected before"
-                                       elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ $ECHO "$logdata"; $ECHO "$diffdata"; } | less -r'; then
-                                               git checkout "$realbase"
-                                               org=`git rev-parse HEAD`
-                                               if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
-                                                       git reset --hard "$org"
-                                                       GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
-                                                       reportdo4 cat "$t"
-                                                       reportecho4 "--> merge failed"
-                                               elif ! "$SELF" compile 2>&1 | tee "$t"; then
-                                                       git reset --hard "$org"
-                                                       GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
-                                                       reportdo4 cat "$t"
-                                                       reportecho4 "--> compile failed"
-                                               elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
-                                                       git reset --hard "$org"
-                                                       GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
-                                                       note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
-                                                       if [ x"$note" = x"del" ]; then
-                                                               git push origin :"${ref#refs/remotes/origin/}"
-                                                               reportecho4 "--> test failed, branch deleted"
-                                                       elif [ -n "$note" ]; then
-                                                               reportdo4 $ECHO "$note"
-                                                               reportecho4 "--> test failed"
-                                                       else
-                                                               reportecho4 "--> test failed, postponed"
-                                                       fi
-                                               else
-                                                       # apply crlf, or other cleanup filters (non-behavioural changes)
-                                                       git reset --hard
-                                                       find . -type f -exec touch {} \;
-                                                       git commit -a --amend -C HEAD || true # don't fail if nothing to commit
-
-                                                       $ECHO "MERGING"
-                                                       case ",`repoflags "$d"`," in
-                                                               *,svn,*)
-                                                                       # we do quite a mess here... luckily we know $org
-                                                                       git fetch # svn needs to be current
-                                                                       git rebase -i --onto origin/master "$org"
-                                                                       git svn dcommit --add-author-from
-                                                                       git reset --hard "$org"
-                                                                       ;;
-                                                               *)
-                                                                       git push origin HEAD
-                                                                       ;;
-                                                       esac
-                                                       reportecho4 "--> MERGED"
-                                                       if yesno "Delete original branch \"$ref\"?"; then
-                                                               git push origin :"${ref#refs/remotes/origin/}"
-                                                               reportecho4 "--> branch deleted"
-                                                       fi
-                                               fi
-                                       else
-                                               GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
-                                               note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
-                                               if [ x"$note" = x"del" ]; then
-                                                       git push origin :"${ref#refs/remotes/origin/}"
-                                                       reportecho4 "--> branch deleted"
-                                               elif [ -n "$note" ]; then
-                                                       reportdo4 $ECHO "$note"
-                                                       reportecho4 "--> rejected"
-                                               else
-                                                       reportecho4 "--> postponed"
-                                               fi
-                                       fi
-                               fi
-                               reportecho ""
-                       done
-                       reportecho ""
-               done
-               rm -f "$t"
-               $ECHO "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
-               ;;
-       clean)
-               "$SELF" fix_config
-               "$SELF" update -N
-               force=false
-               gotoupstream=false
-               fetchupstream=false
-               gotomaster=false
-               rmuntracked=false
-               killbranches=false
-               # usage:
-               #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
-               #   ./all clean --reclone
-               found=false
-               for X in "$@"; do
-                       if [ x"$X" = x"--reclone" ]; then
-                               force=true
-                               fetchupstream=true
-                               gotoupstream=true
-                               gotomaster=true
-                               rmuntracked=true
-                               killbranches=true
-                       elif [ x"$X" = x"-f" ]; then
-                               force=true
-                       elif [ x"$X" = x"-u" ]; then
-                               gotoupstream=true
-                       elif [ x"$X" = x"-U" ]; then
-                               gotoupstream=true
-                               fetchupstream=true
-                       elif [ x"$X" = x"-fu" ]; then
-                               force=true
-                               gotoupstream=true
-                       elif [ x"$X" = x"-fU" ]; then
-                               force=true
-                               gotoupstream=true
-                               fetchupstream=true
-                       elif [ x"$X" = x"-m" ]; then
-                               gotomaster=true
-                       elif [ x"$X" = x"-r" ]; then
-                               rmuntracked=true
-                       elif [ x"$X" = x"-D" ]; then
-                               killbranches=true
-                       elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
-                               msg ''
-                               msg "        _____"
-                               msg "    ,--'-\\P/\`\\  FFFFFFF"
-                               msg " __/_    B/,-.\\  FFFFFFF"
-                               msg " /  _\\  (//  O\\\\  FFFFFF"
-                               msg "| (O  \`) _\\._ _)\\  FFFUU"
-                               msg "| |___/.^d0~~\"\\  \\ UUUU"
-                               msg "|     |\`~'     \\ |  UUUU"
-                               msg "|     |    __,C>|| UUUU"
-                               msg "\\    /_ ,-/,-'   |  UUUU"
-                               msg " \\\\_ \\_>~'      /  UUUU-"
-                               msg ''
-                       else
-                               msg "Unknown arg: $X"
-                       fi
-                       found=true
-               done
-               if ! $found; then
-                       rmuntracked=true
-               fi
-               for d in $repos; do
-                       verbose cd "$d0/$d"
-                       if $gotoupstream; then
-                               if ! $force; then
-                                       msg "Must also use -f (delete local changes) when using -u"
-                                       exit 1
-                               fi
-                               if $gotomaster; then
-                                       if $fetchupstream; then
-                                               verbose git fetch origin
-                                               verbose git remote prune origin
-                                       fi
-                                       verbose git checkout -f "`repobranch "$d"`"
-                                       verbose git reset --hard origin/"`repobranch "$d"`"
-                               else
-                                       r=`git symbolic-ref HEAD`
-                                       r=${r#refs/heads/}
-                                       rem=`git config "branch.$r.remote" || $ECHO origin`
-                                       bra=`git config "branch.$r.merge" || $ECHO "$r"`
-                                       upstream="$rem/${bra#refs/heads/}"
-                                       if $fetchupstream; then
-                                               verbose git fetch "$rem"
-                                               verbose git remote prune "$rem"
-                                       fi
-                                       if ! git rev-parse "$upstream" >/dev/null 2>&1; then
-                                               upstream="origin/`repobranch "$d"`"
-                                       fi
-                                       verbose git reset --hard "$upstream"
-                               fi
-                       elif $gotomaster; then
-                               if $force; then
-                                       verbose git checkout -f "`repobranch "$d"`"
-                                       verbose git reset --hard
-                               else
-                                       verbose git checkout "`repobranch "$d"`"
-                               fi
-                       elif $force; then
-                               verbose git reset --hard
-                       fi
-                       if $rmuntracked; then
-                               case "$d" in
-                                       .)
-                                               verbose git clean -df || true
-                                               ;;
-                                       *)
-                                               verbose git clean -xdf || true
-                                               ;;
-                               esac
-                       fi
-                       if $killbranches; then
-                               git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
-                                       if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
-                                               verbose git branch -D "${B#refs/heads/}"
-                                       fi
-                               done
-                               git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
-                               git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch --track "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
-                       fi
-                       checkself "$cmd" "$@"
-               done
-               ;;
-
-       # release building goes here
-       release-prepare)
-               #"$SELF" each git clean -fxd
-               case "$RELEASETYPE" in
-                       '')
-                               $ECHO >&2 -n "$ESC[2J$ESC[H"
-                               msg ""
-                               msg ""
-                               msg ""
-                               msg ""
-                               msg ""
-                               msg ""
-                               msg "        +---------------------------------------------------------.---+"
-                               msg "        | NOTE                                                    | X |"
-                               msg "        +---------------------------------------------------------^---+"
-                               msg "        |   ____                                                      |"
-                               msg "        |  /    \  This is the official release build system.         |"
-                               msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
-                               msg "        | | STOP | you are not supposed to use this script and should |"
-                               msg "        | |      | instead use ./all compile to compile the engine    |"
-                               msg "        |  \____/  and game code.                                     |"
-                               msg "        |                                                             |"
-                               msg "        |                      [ I understand ]                       |"
-                               msg "        +-------------------------------------------------------------+"
-                               sleep 10
-                               # A LOT of build infrastructure is required:
-                               # - vorbis-tools
-                               # - ImageMagick
-                               # - .ssh/config must be configured so the following
-                               #   host names are reachable and have a compile
-                               #   infrastructure set up:
-                               #   - xonotic-build-linux32 (with gcc on x86)
-                               #   - xonotic-build-linux64 (with gcc on x86_64)
-                               #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
-                               #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
-                               #     and x86_64-w64-mingw32-g++)
-                               #   - xonotic-build-osx (with Xcode and SDL.framework)
-                               # - AMD Compressonator installed in WINE
-                               # - ResEdit installed in WINE
-                               # - a lot of other requirements you will figure out
-                               #   while reading the error messages
-                               # - environment variable RELEASETYPE set
-                               # - optionally, environment variable RELEASEDATE set
-                               #   (YYYYMMDD)
-                               exit 1
-                               ;;
-                       release)
-                               msg "Building a FINISHED RELEASE"
-                               ;;
-                       *)
-                               msg "Building a $RELEASETYPE"
-                               ;;
-               esac
-               verbose rm -rf Xonotic Xonotic*.zip
-               verbose mkdir -p Xonotic
-               if [ -n "$RELEASEDATE" ]; then
-                       verbose $ECHO "$RELEASEDATE" > Xonotic/stamp.txt
-               else
-                       verbose date +%Y%m%d > Xonotic/stamp.txt
-               fi
-               release_git_extract_dir "." "Xonotic" Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk COPYING GPL-2 GPL-3
-               (
-                       verbose cd Xonotic
-                       verbose mkdir data fteqcc source source/darkplaces source/fteqcc source/d0_blind_id mapping
-                       verbose rm -rf misc/builddeps
-                       verbose mv misc/buildfiles/win32 bin32 || true
-                       verbose mv bin32/SDL.dll . || true
-                       verbose mv misc/buildfiles/win64 bin64 || true
-                       verbose mv misc/buildfiles/osx/* . || true
-                       verbose rm -rf misc/buildfiles
-                       verbose rm -rf misc/pki
-               )
-               release_git_extract_dir "darkplaces" "Xonotic/source/darkplaces" .
-               release_git_extract_dir "fteqcc" "Xonotic/source/fteqcc" .
-               release_git_extract_dir "data/xonotic-data.pk3dir" "Xonotic/source" qcsrc Makefile
-               release_git_extract_dir "d0_blind_id" "Xonotic/source/d0_blind_id" .
-               (
-                       verbose cd Xonotic/source/d0_blind_id
-                       verbose sh autogen.sh
-               )
-               rm -f Xonotic/key_15.d0pk
-               {
-                       verbose cd Xonotic/mapping
-                       verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20120114.tar.bz2
-                       verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20120114-win32-7z.exe
-                       for X in *-7z.exe; do
-                               7za x "$X"
-                               rm -f "$X"
-                       done
-                       # TODO possibly include other tools?
-               }
-               ;;
-       release-compile-run)
-               host=$1
-               buildpath=$2
-               maketargets=$3
-               makeflags=$4
-               srcdir=$5
-               depsdir=$6
-               targetfiles=$7
-               set -x
-               if [ -n "$targetfiles" ]; then
-                       case " $HOSTS_THAT_ARE_DISABLED " in
-                               *\ $host\ *)
-                                       exit
-                                       ;;
-                       esac
-                       case " $HOSTS_THAT_ARE_MYSELF " in
-                               *\ $host\ *)
-                                       verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
-                                       verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
-                                       verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
-                                       verbose eval make -C "$buildpath" clean $maketargets $makeflags
-                                       for f in $targetfiles; do
-                                               verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
-                                       done
-                                       ;;
-                               *)
-                                       verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
-                                       verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
-                                       verbose ssh "$host" "[ -f /etc/profile ] && . /etc/profile; [ -f ~/.profile ] && . ~/.profile; export LC_ALL=C; ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
-                                       for f in $targetfiles; do
-                                               verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
-                                       done
-                                       ;;
-                       esac
-                       # now rebrand the binaries...
-                       for f in $targetfiles; do
-                               #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
-                               case "${f##*:}" in
-                                       Xonotic/xonotic*.exe)
-                                               verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
-                                               ;;
-                               esac
-                       done
-               fi
-               ;;
-       release-compile)
-               suffix=$1
-               makeflags=$2
-               fteqcc_maketargets=$3
-               fteqcc_files=$4
-               darkplaces_maketargets=$5
-               darkplaces_files=$6
-               host=xonotic-build-$suffix
-               verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
-               verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
-               ;;
-       release-engine-win32)
-               verbose "$SELF" release-compile win32 \
-                       'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-gcc -march=i686 -g1 -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' \
-                       win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
-                       '' ''
-               verbose "$SELF" release-compile win32 \
-                       'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-g++ -g1 -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=1' \
-                       '' '' \
-                       release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
-               ;;
-       release-engine-win64)
-               verbose "$SELF" release-compile win64 \
-                       'STRIP=: DP_MAKE_TARGET=mingw CC="amd64-mingw32msvc-gcc -g1 -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' \
-                       win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
-                       'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
-               verbose "$SELF" release-compile win64 \
-                       'STRIP=: DP_MAKE_TARGET=mingw CC="x86_64-w64-mingw32-g++ -g1 -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=1' \
-                       '' '' \
-                       cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
-               ;;
-       release-engine-osx)
-               # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
-               verbose "$SELF" release-compile osx \
-                       'STRIP=: CC="gcc -g1 -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"' \
-                       all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
-                       'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
-               ;;
-       release-engine-linux32)
-               verbose "$SELF" release-compile linux32 \
-                       'STRIP=: CC="gcc -m32 -march=i686 -g1 -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' \
-                       all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
-                       release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
-               ;;
-       release-engine-linux64)
-               verbose "$SELF" release-compile linux64 \
-                       'STRIP=: CC="gcc -m64 -g1 -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' \
-                       all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
-                       release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
-               ;;
-       release-engine)
-               verbose "$SELF" release-engine-linux32 &
-               verbose "$SELF" release-engine-linux64 &
-               verbose "$SELF" release-engine-win32 &
-               verbose "$SELF" release-engine-win64 &
-               verbose "$SELF" release-engine-osx &
-               wait %1
-               wait %2
-               wait %3
-               wait %4
-               wait %5
-               wait
-               ;;
-       release-maps)
-               verbose "$SELF" update-maps
-               ;;
-       release-qc)
-               verbose env GIT_DIR="$d0/data/xonotic-data.pk3dir/.git" make -C Xonotic/source FTEQCC="$d0/Xonotic/fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
-               verbose rm -f Xonotic/source/qcsrc/*/fteqcc.log
-               ;;
-       release-buildpk3-transform-raw)
-               dir=$1
-               ;;
-       release-buildpk3-transform-normal)
-               dir=$1
-               verbose cd "$dir"
-               # texture: convert to jpeg and dds
-               verbose export do_jpeg=true
-               verbose export jpeg_qual_rgb=97
-               verbose export jpeg_qual_a=99
-               verbose export do_dds=false
-               verbose export do_ogg=true
-               verbose export ogg_ogg=false
-               verbose export del_src=true
-               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
-               ;;
-       release-buildpk3-transform-normaldds)
-               dir=$1
-               verbose cd "$dir"
-               # texture: convert to jpeg and dds
-               # music: reduce bitrate
-               verbose export do_jpeg=false
-               verbose export do_jpeg_if_not_dds=true
-               verbose export jpeg_qual_rgb=95
-               verbose export jpeg_qual_a=99
-               verbose export do_dds=true
-               verbose export dds_flags=
-               verbose export do_ogg=true
-               verbose export ogg_ogg=false
-               verbose export del_src=true
-               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
-               ;;
-       release-buildpk3-transform-low)
-               dir=$1
-               verbose cd "$dir"
-               # texture: convert to jpeg and dds
-               # music: reduce bitrate
-               verbose export do_jpeg=true
-               verbose export jpeg_qual_rgb=80
-               verbose export jpeg_qual_a=97
-               verbose export do_dds=false
-               verbose export do_ogg=true
-               verbose export ogg_qual=1
-               verbose export del_src=true
-               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
-               ;;
-       release-buildpk3-transform-lowdds)
-               dir=$1
-               verbose cd "$dir"
-               # texture: convert to jpeg and dds
-               # music: reduce bitrate
-               verbose export do_jpeg=false
-               verbose export do_jpeg_if_not_dds=true
-               verbose export jpeg_qual_rgb=80
-               verbose export jpeg_qual_a=99
-               verbose export do_dds=true
-               verbose export dds_flags=
-               verbose export do_ogg=true
-               verbose export ogg_qual=1
-               verbose export del_src=true
-               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
-               ;;
-       release-buildpk3-transform-mapping)
-               dir=$1
-               verbose cd "$dir"
-               # remove stuff radiant has no use for
-               verbose find . -name \*_norm.\* -exec rm -f {} \;
-               verbose find . -name \*_bump.\* -exec rm -f {} \;
-               verbose find . -name \*_glow.\* -exec rm -f {} \;
-               verbose find . -name \*_gloss.\* -exec rm -f {} \;
-               verbose find . -name \*_pants.\* -exec rm -f {} \;
-               verbose find . -name \*_shirt.\* -exec rm -f {} \;
-               verbose find . -name \*_reflect.\* -exec rm -f {} \;
-               verbose find . -not \( -name \*.tga -o -name \*.png -o -name \*.jpg \) -exec rm -f {} \;
-               # texture: convert to jpeg and dds
-               # music: reduce bitrate
-               verbose export do_jpeg=true
-               verbose export jpeg_qual_rgb=80
-               verbose export jpeg_qual_a=97
-               verbose export do_dds=false
-               verbose export do_ogg=true
-               verbose export ogg_qual=1
-               verbose export del_src=true
-               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
-               ;;
-       release-buildpk3)
-               src=$1
-               dst=$2
-               transform=$3
-               case "$dst" in
-                       /*)
-                               ;;
-                       */)
-                               dst="$PWD/$dst"
-                               ;;
-               esac
-               release_timereport
-               verbose rm -rf Xonotic/temp
-               release_timereport "deleted temp directory"
-               verbose mkdir -p Xonotic/temp
-               release_git_extract_dir "$src" "Xonotic/temp" .
-               release_timereport "extracted data"
-               verbose cd Xonotic/temp
-               if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
-                       verbose cp ../source/progs.dat .
-                       verbose cp ../source/csprogs.dat .
-                       verbose cp ../source/menu.dat .
-                       verbose rm -rf qcsrc
-                       gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
-                       major=$(($gv / 10000))
-                       minor=$((($gv / 100) - ($major * 100)))
-                       patch=$(($gv - ($major * 10000) - ($minor * 100)))
-                       versionstr="$major.$minor.$patch"
-                       case "$RELEASETYPE" in
-                               release)
-                                       ;;
-                               *)
-                                       versionstr="$versionstr$RELEASETYPE"
-                                       ;;
-                       esac
-                       if [ $gv -lt 9900 ]; then
-                               # pre-1.0: compatible with any other pre-1.0
-                               verbose sed "
-                                       s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
-                                       s/^gameversion_min [0-9]*/gameversion_min     0/;
-                                       s/^gameversion_max [0-9]*/gameversion_max  9999/;
-                               " < defaultXonotic.cfg > defaultXonotic.cfg.new
-                       else
-                               # >= 1.0
-                               verbose sed "
-                                       s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
-                                       s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
-                                       s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
-                               " < defaultXonotic.cfg > defaultXonotic.cfg.new
-                       fi
-                       mv defaultXonotic.cfg.new defaultXonotic.cfg
-                       case "$RELEASETYPE" in
-                               release)
-                                       echo "" >> defaultXonotic.cfg
-                                       echo "// nicer menu" >> defaultXonotic.cfg
-                                       echo "set menu_watermark \"\"" >> defaultXonotic.cfg
-                                       ;;
-                       esac
-                       (
-                               verbose cd gfx/menu/luminos
-                               verbose rm -f background_l2.tga background_ingame_l2.tga
-                               verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
-                               verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
-                               verbose rm background_l2.svg
-                       )
-               fi
-               if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
-                       for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
-                               if [ -f "$X" ]; then
-                                       verbose unzip "$X"
-                                       verbose rm -f maps/*.log maps/*.irc maps/*.lin
-                               fi
-                       done
-               fi
-               verbose export git_src_repo="$d0/$src" # skip hash-object
-               release_timereport "processed data"
-               verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
-               release_timereport "transformed data"
-               find . -type f -size +4k | verbose "$d0"/misc/tools/symlink-deduplicate.sh
-               release_timereport "deduplicated data"
-               verbose mkzipr "../../$dst" *
-               release_timereport "zipped data"
-               verbose cd ../..
-               verbose rm -rf Xonotic/temp
-               release_timereport "deleted temp directory again"
-               ;;
-       release-buildpk3s)
-               stamp=`cat Xonotic/stamp.txt`
-               src=$1
-               shift
-               dst=${src%.pk3dir}
-               case "$dst" in
-                       data/xonotic-*)
-                               dst="data/xonotic-$stamp-${dst#data/xonotic-}"
-                               ;;
-                       *)
-                               dst="$dst-$stamp"
-                               ;;
-               esac
-               while [ "$#" -gt 1 ]; do
-                       verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
-                       shift
-                       shift
-               done
-               ;;
-       release-pack)
-               verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir                  raw ''
-               verbose "$SELF" release-buildpk3s data/font-xolonium.pk3dir                     raw ''
-               verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal '-high'        low '-low' normaldds ''
-               verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal '-high'        low '-low' normaldds '' mapping '-mapping'
-               verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                     raw '' low '-low'
-               verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir  normal '-high'                   normaldds ''
-               ;;
-       release-pack-needsx11)
-               case "$DISPLAY" in
-                       '')
-                               verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
-                               ;;
-                       *)
-                               verbose "$SELF" release-pack
-                               ;;
-               esac
-               ;;
-       release-zip)
-               stamp=`cat Xonotic/stamp.txt`
-               # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
-               chmod a-x Xonotic/*.exe Xonotic/*.dll || true
-               # let's pass crypto import laws of some nasty countries
-               crypto_libs=`find Xonotic -name \*d0_rijndael\*.so -o -name \*d0_rijndael\*.dylib -o -name \*d0_rijndael\*.dll -o -name \*d0_rijndael\*.c`
-               if [ -n "$crypto_libs" ]; then
-                       verbose mkzip Xonotic-$stamp-crypto.zip \
-                               $crypto_libs \
-                               Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
-                       rm -f $crypto_libs
-               fi
-               # build the archives
-               verbose mkzip Xonotic-$stamp-enginesource.zip \
-                       Xonotic/source/darkplaces/ \
-                       Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
-               verbose cp Xonotic-$stamp-enginesource.zip Xonotic-$stamp-engine.zip
-               verbose mkzip Xonotic-$stamp-engine.zip \
-                       Xonotic/*.dll \
-                       Xonotic/bin32/*.dll \
-                       Xonotic/bin64/*.dll \
-                       Xonotic/*.app \
-                       Xonotic/xonotic-* \
-                       Xonotic/xonotic.exe
-               verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
-               verbose mkzip Xonotic-$stamp-common.zip \
-                       Xonotic/source/fteqcc/ \
-                       Xonotic/source/qcsrc/ \
-                       Xonotic/Docs \
-                       Xonotic/misc \
-                       Xonotic/fteqcc \
-                       Xonotic/server \
-                       Xonotic/key_0.d0pk \
-                       Xonotic/data/font-nimbussansl-$stamp.pk3 \
-                       Xonotic/data/font-xolonium-$stamp.pk3
-               verbose cp Xonotic-$stamp-enginesource.zip Xonotic-$stamp-source.zip
-               verbose mkzip Xonotic-$stamp-source.zip \
-                       Xonotic/source/fteqcc/ \
-                       Xonotic/source/qcsrc/ \
-                       Xonotic/misc/logos
-               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
-               verbose mkzip0 Xonotic-$stamp.zip \
-                       Xonotic/data/xonotic-$stamp-data.pk3 \
-                       Xonotic/data/xonotic-$stamp-maps.pk3 \
-                       Xonotic/data/xonotic-$stamp-music.pk3 \
-                       Xonotic/data/xonotic-$stamp-nexcompat.pk3
-               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
-               verbose mkzip0 Xonotic-$stamp-low.zip \
-                       Xonotic/data/xonotic-$stamp-data-low.pk3 \
-                       Xonotic/data/xonotic-$stamp-maps-low.pk3 \
-                       Xonotic/data/xonotic-$stamp-music-low.pk3
-               verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
-               verbose mkzip Xonotic-$stamp-high.zip \
-                       Xonotic/mapping
-               verbose mkzip0 Xonotic-$stamp-high.zip \
-                       Xonotic/data/xonotic-$stamp-data-high.pk3 \
-                       Xonotic/data/xonotic-$stamp-maps-high.pk3 \
-                       Xonotic/data/xonotic-$stamp-music.pk3 \
-                       Xonotic/data/xonotic-$stamp-nexcompat-high.pk3
-               verbose mkzip Xonotic-$stamp-mappingsupport.zip \
-                       Xonotic/mapping
-               verbose mkzip0 Xonotic-$stamp-mappingsupport.zip \
-                       Xonotic/data/xonotic-$stamp-maps-mapping.pk3
-               ;;
-       release)
-               verbose "$SELF" release-prepare
-               verbose "$SELF" release-maps
-               verbose "$SELF" release-engine
-               verbose "$SELF" release-qc
-               verbose "$SELF" release-pack-needsx11
-               verbose "$SELF" release-zip
-               ;;
-
-       *)
-               $ECHO "Usage:"
-               $ECHO "  $SELF admin-merge [<branch>]"
-               $ECHO "  $SELF branch <branch>"
-               $ECHO "  $SELF branch <remote> <branch> [<srcbranch>]"
-               $ECHO "  $SELF branches"
-               $ECHO "  $SELF checkout|switch <branch>"
-               $ECHO "  $SELF checkout|switch <remote>/<branch>"
-               $ECHO "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
-               $ECHO "  $SELF clean --reclone"
-               $ECHO "  $SELF compile [-c] [-r|-p] [-0] [sdl|glx|wgl|agl|dedicated]"
-               $ECHO "  $SELF each|foreach [-k] command..."
-               $ECHO "  $SELF fix_upstream_rebase"
-               $ECHO "  $SELF keygen"
-               $ECHO "  $SELF merge"
-               $ECHO "  $SELF push|commit [-s]"
-               $ECHO "  $SELF restore-patches"
-               $ECHO "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
-               $ECHO "  $SELF save-patches"
-               $ECHO "  $SELF update-maps"
-               $ECHO "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
-               ;;
-esac
+fi
diff --git a/misc/tools/all/config.subr b/misc/tools/all/config.subr
new file mode 100644 (file)
index 0000000..69d280d
--- /dev/null
@@ -0,0 +1,150 @@
+devsite_url="http://dev.xonotic.org/"
+pushsite_url="ssh://xonotic@push.git.xonotic.org/"
+httppushsite_url="http://push.git.xonotic.org/login/xonotic/"
+gitsite_url="git://git.xonotic.org/xonotic/"
+httpsite_url="http://git.xonotic.org/xonotic/"
+
+repos_urls="
+.                             |                                                   | master         |
+data/xonotic-data.pk3dir      |                                                   | master         |
+data/xonotic-music.pk3dir     |                                                   | master         |
+data/xonotic-nexcompat.pk3dir |                                                   | master         | no
+darkplaces                    |                                                   | div0-stable    | svn
+netradiant                    |                                                   | master         |
+div0-gittools                 |                                                   | master         | no
+d0_blind_id                   |                                                   | master         |
+data/xonotic-maps.pk3dir      |                                                   | master         |
+mediasource                   |                                                   | master         | no
+fteqcc                        |                                                   | xonotic-stable | noautocrlf
+"
+# todo: in darkplaces, change repobranch to div0-stable
+
+repos=`$ECHO "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
+
+base=`git config remote.origin.url`
+case "$base" in
+       */xonotic.git)
+               base=${base%xonotic.git}
+               ;;
+       *)
+               $ECHO "The main repo is not xonotic.git, what have you done?"
+               exit 1
+               ;;
+esac
+pushbase=`git config remote.origin.pushurl || true`
+case "$pushbase" in
+       */xonotic.git)
+               pushbase=${pushbase%xonotic.git}
+               ;;
+       '')
+               ;;
+       *)
+               $ECHO "The main repo is not xonotic.git, what have you done?"
+               exit 1
+               ;;
+esac
+
+repourl()
+{
+       repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
+       if [ -n "$repo_t" ]; then
+               case "$repo_t" in
+                       *://*)
+                               $ECHO "$repo_t"
+                               ;;
+                       *)
+                               $ECHO "$base$repo_t"
+                               ;;
+               esac
+       else
+               if [ x"$1" = x"." ]; then
+                       $ECHO "$base""xonotic.git"
+               else
+                       $ECHO "$base${1##*/}.git"
+               fi
+       fi
+}
+
+repopushurl()
+{
+       [ -n "$pushbase" ] || return 0
+       repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
+       if [ -n "$repo_t" ]; then
+               case "$repo_t" in
+                       *://*)
+                               ;;
+                       *)
+                               $ECHO "$pushbase$repo_t"
+                               ;;
+               esac
+       else
+               if [ x"$1" = x"." ]; then
+                       $ECHO "$pushbase""xonotic.git"
+               else
+                       $ECHO "$pushbase${1##*/}.git"
+               fi
+       fi
+}
+
+repobranch()
+{
+       repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
+       if [ -n "$repo_t" ]; then
+               $ECHO "$repo_t"
+       else
+               $ECHO "master"
+       fi
+}
+
+repoflags()
+{
+       $ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 4 | tr -d ' '
+}
+
+listrepos()
+{
+       for d in $repos; do
+               p="${d%dir}"
+               f="`repoflags "$d"`"
+               # if we have .no file, skip
+               if [ -f "$d.no" ]; then
+                       msg "Repository $d disabled by a .no file, delete $d.no to enable"
+                       continue
+               fi
+               # if .yes file exists, always keep it
+               if [ -f "$d.yes" ]; then
+                       msg "Repository $d enabled by a .yes file"
+                       $ECHO "$d"
+                       continue
+               fi
+               # remove broken clones so they don't mess up stuff
+               if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
+                       msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
+                       verbose rm -rf "$d"
+                       continue
+               fi
+               # if we have the dir, always keep it
+               if [ -d "$d" ]; then
+                       msg "Repository $d enabled because it already exists"
+                       $ECHO "$d"
+                       continue
+               fi
+               # if we have matching pk3, skip
+               if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
+                       msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
+                       continue
+               fi
+               # if "no" flag is set, skip
+               case ",$f," in
+                       *,no,*)
+                               msg "Repository $d disabled by default, create $d.yes to enable"
+                               continue
+                               ;;
+               esac
+               # default: enable
+               msg "Repository $d enabled by default"
+               $ECHO "$d"
+       done
+}
+
+repos=`listrepos`
diff --git a/misc/tools/all/git.subr b/misc/tools/all/git.subr
new file mode 100644 (file)
index 0000000..b2b8423
--- /dev/null
@@ -0,0 +1,721 @@
+check_mergeconflict() # overrides the one in ./all
+{
+       if git ls-files -u | grep ' 1   '; then
+               $ECHO
+               $ECHO "MERGE CONFLICT."
+               $ECHO "change into the \"$1\" project directory, and then:"
+               $ECHO "- edit the files mentioned above with your favorite editor,"
+               $ECHO "  and fix the conflicts (marked with <<<<<<< blocks)"
+               $ECHO "- for binary files, you can select the files using"
+               $ECHO "  git checkout --ours or git checkout --theirs"
+               $ECHO "- when done with a file, 'git add' the file"
+               $ECHO "- when done, 'git commit'"
+               $ECHO
+               exit 1
+       fi
+}
+
+visible_repo_name()
+{
+       case "$1" in
+               .)
+                       $ECHO "the root directory"
+                       ;;
+               *)
+                       $ECHO "\"$1\""
+                       ;;
+       esac
+}
+
+fix_upstream_rebase()
+{
+       if [ -z "$r_me" ] || [ -z "$r_other" ]; then
+               return
+       fi
+
+       # one of the two sides of the merge should be remote upstream, or all is fine
+       r_r=`git symbolic-ref HEAD`
+       r_r=${r_r#refs/heads/}
+       r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
+       r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
+       r_bra=${r_bra#refs/heads/}
+       if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
+               if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
+                       return
+               fi
+       fi
+
+       r_base=`git merge-base "$r_me" "$r_other"`
+
+       # no merge-base? upstream did filter-branch
+       if [ -n "$r_base" ]; then
+               # otherwise, check if the two histories are "similar"
+               r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
+               r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
+
+               # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
+               r_lc_me=`$ECHO "$r_l_me" | wc -l`
+               r_lc_other=`$ECHO "$r_l_other" | wc -l`
+               r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
+               r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
+
+               if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
+                       if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
+                               git reset --hard "$r_me"
+                               git pull --rebase
+                               return 1
+                       fi
+               fi
+       fi
+
+       return 0
+}
+
+fix_upstream_rebase_mergeok()
+{
+       r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
+       r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
+       fix_upstream_rebase
+}
+
+fix_upstream_rebase_mergefail()
+{
+       r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
+       r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
+       fix_upstream_rebase
+}
+
+fix_git_config()
+{
+       if ! [ -f ".git/config" ]; then
+               $ECHO "Not a git repository. Bailing out to not cause damage."
+               exit 1
+       fi
+       verbose git config remote.origin.url "$1"
+       if [ -n "$2" ]; then
+               verbose git config remote.origin.pushurl "$2"
+       else
+               verbose git config --unset remote.origin.pushurl || true
+       fi
+       verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
+       case ",`repoflags "$d"`," in
+               *,noautocrlf,*)
+                       verbose git config --unset core.autocrlf || true
+                       ;;
+               *)
+                       verbose git config core.autocrlf input
+                       ;;
+       esac
+       if [ -z "`git config push.default || true`" ]; then
+               verbose git config push.default current # or is tracking better?
+       fi
+       verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
+       verbose git config filter.mapclean.smudge "cat"
+}
+
+mirrorspeed()
+{
+       # first result is to be ignored, but we use it to check status
+       git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
+       { time -p git ls-remote "$1" refs/heads/master; } 2>&1 >/dev/null | head -n 1 | cut -d ' ' -f 2 | tr -d . | sed 's,^0*,,'
+               # unit: clock ticks (depends on what "time" returns
+}
+
+bestmirror()
+{
+       pre=$1; shift
+       suf=$1; shift
+
+       if ! { time -p true; } >/dev/null 2>&1; then
+               msg "Cannot do timing in this shell"
+               return 1
+       fi
+
+       bestin=
+       bestt=
+       for mir in "$@"; do
+               case "$mir" in
+                       *:*)
+                               in=${mir%%:*}
+                               op=${mir#*:}
+                               ;;
+                       *)
+                               in=$mir
+                               op=
+                               ;;
+               esac
+               m=$pre$in$suf
+               if t=`mirrorspeed "$m"`; then
+                       if [ -n "$t" ]; then
+                               tt=$(($t$op)) # fudge factor
+                               msg "$m -> $t$op = $tt ticks"
+                               if [ -z "$bestt" ] || [ "$tt" -lt "$bestt" ]; then
+                                       bestin=$in
+                                       bestt=$tt
+                               fi
+                       else
+                               msg "$m -> error"
+                       fi
+               else
+                       msg "$m -> FAIL"
+               fi
+       done
+       if [ -n "$bestin" ]; then
+               msg "Best mirror seems to be $pre$bestin$suf"
+               $ECHO "$bestin"
+       else
+               return 1
+       fi
+}
+
+handled=true
+case "$cmd" in
+       fix_upstream_rebase)
+               for d in $repos; do
+                       enter "$d0/$d" verbose
+                       verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
+               done
+               ;;
+       fix_config)
+               for d in $repos; do
+                       url=`repourl "$d"`
+                       pushurl=`repopushurl "$d"`
+                       branch=`repobranch "$d"`
+                       if [ -f "$d0/$d/.git/config" ]; then
+                               verbose cd "$d0/$d"
+                               fix_git_config "$url" "$pushurl"
+                               cd "$d0"
+                       fi
+               done
+               ;;
+       keygen)
+               # enable the ssh URL for pushing
+               "$SELF" update -N -p
+
+               if [ -f ~/.ssh/id_rsa.pub ]; then
+                       msg ""
+                       msg "A key already exists and no new one will be generated. If you"
+                       msg "already have done the procedure for getting your key approved, you"
+                       msg "can skip the following paragraph and already use the repository."
+                       msg ""
+                       msg "To get access, your key has to be approved first. For that, visit"
+                       msg "$devsite_url, then log in, create a \"New Issue\" on"
+                       msg "the \"Support\" tracker in the \"Repository\" category where you"
+                       msg "apply for access and paste the following output into the issue:"
+                       msg ""
+                       msg "`cat ~/.ssh/id_rsa.pub`"
+                       msg ""
+                       msg "Note that you will only have write access to branches that start"
+                       msg "with your user name."
+               elif [ -f ~/.ssh/id_dsa.pub ]; then
+                       msg ""
+                       msg "A key already exists and no new one will be generated. If you"
+                       msg "already have done the procedure for getting your key approved, you"
+                       msg "can skip the following paragraph and already use the repository."
+                       msg ""
+                       msg "To get access, your key has to be approved first. For that, visit"
+                       msg "$devsite_url, then log in, create a \"New Issue\" on"
+                       msg "the \"Support\" tracker in the \"Repository\" category where you"
+                       msg "apply for access and paste the following output into the issue:"
+                       msg ""
+                       msg "`cat ~/.ssh/id_dsa.pub`"
+                       msg ""
+                       msg "Note that you will only have write access to branches that start"
+                       msg "with your user name."
+               else
+                       msg ""
+                       msg "No key has been generated yet. One will be generated now."
+                       msg "If other people are using your computer, it is recommended"
+                       msg "to specify a passphrase. Otherwise you can simply hit ENTER"
+                       msg "when asked for a passphrase."
+                       msg ""
+                       ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
+                       msg ""
+                       msg "To get access, your key has to be approved first. For that, visit"
+                       msg "$devsite_url, then log in, create a \"New Issue\" on"
+                       msg "the \"Support\" tracker in the \"Repository\" category where you"
+                       msg "apply for access and paste the following output into the issue:"
+                       msg ""
+                       msg "`cat ~/.ssh/id_rsa.pub`"
+                       msg ""
+                       msg "Note that you will only have write access to branches that start"
+                       msg "with your user name."
+               fi
+               ;;
+       update|pull)
+               allow_pull=true
+               location=current
+               oldbase=$base
+               oldpushbase=$pushbase
+               while :; do
+                       if [ x"$1" = x"-N" ]; then
+                               allow_pull=false
+                       elif [ x"$1" = x"-p" ]; then
+                               pushbase=$pushsite_url
+                       elif [ x"$1" = x"-ps" ]; then
+                               pushbase=$pushsite_url
+                       elif [ x"$1" = x"-ph" ]; then
+                               pushbase=$httppushsite_url
+                       elif [ x"$1" = x"-s" ]; then
+                               base=$pushsite_url
+                       elif [ x"$1" = x"-g" ]; then
+                               base=$gitsite_url
+                               location=best
+                       elif [ x"$1" = x"-h" ]; then
+                               base=$httpsite_url
+                               location=best
+                       elif [ x"$1" = x"-l" ]; then
+                               case "$2" in
+                                       nl) ;;
+                                       de) ;;
+                                       us) ;;
+                                       best) ;;
+                                       default) ;;
+                                       *)
+                                               msg "Invalid location!"
+                                               msg "Possible locations for the -l option:"
+                                               msg "  nl (Netherlands, run by merlijn)"
+                                               msg "  de (Germany, run by divVerent)"
+                                               msg "  us (United States of America, run by detrate)"
+                                               msg "  best (find automatically)"
+                                               msg "  default (currently nl)"
+                                               exit 1
+                                               ;;
+                               esac
+                               location=$2
+                               shift
+                       else
+                               break
+                       fi
+                       shift
+               done
+               case "$location" in
+                       current)
+                               if [ x"`git config xonotic.all.mirrorselection 2>/dev/null || true`" != x"done" ]; then
+                                       location=best
+                               fi
+                               ;;
+               esac
+               case "$location" in
+                       best)
+                               # if we fetched via ssh://, switch to git:// for fetching and keep using ssh:// for pushing
+                               case "$base" in
+                                       ssh://*|*/login/*)
+                                               pushbase=$base
+                                               base=$gitsite_url
+                                               ;;
+                               esac
+                               newbase=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,:// .git.xonotic.org/,"`
+                               case "$newbase" in
+                                       *\ *)
+                                               if location=`bestmirror $newbase"xonotic.git" de us nl:'*6/5'`; then # 20% malus to the NL server to not overload it too much
+                                                       git config xonotic.all.mirrorselection done
+                                               else
+                                                       location=current
+                                               fi
+                                               ;;
+                                       *)
+                                               location=current
+                                               ;;
+                               esac
+                               ;;
+               esac
+               case "$location" in
+                       default)
+                               location=
+                               ;;
+                       current)
+                               case "$base" in
+                                       *://*.git.xonotic.org/*)
+                                               location=${base%%.git.xonotic.org/*}
+                                               location=${location##*://}
+                                               ;;
+                                       *)
+                                               location=
+                                               ;;
+                               esac
+                               ;;
+               esac
+               if [ -n "$location" ]; then
+                       base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
+               else
+                       base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
+               fi
+               pushbase=`$ECHO "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://xonotic@push.git.xonotic.org/,"`
+               if [ x"$base" != x"$oldbase" ] || [ x"$pushbase" != x"$oldpushbase" ]; then
+                       url=`repourl .`
+                       pushurl=`repopushurl .`
+                       fix_git_config "$url" "$pushurl"
+                       "$SELF" fix_config
+               elif $allow_pull; then
+                       "$SELF" fix_config
+               fi
+               for d in $repos; do
+                       url=`repourl "$d"`
+                       pushurl=`repopushurl "$d"`
+                       branch=`repobranch "$d"`
+                       if [ -f "$d0/$d/.git/config" ]; then
+                               # if we have .no file, skip
+                               if [ -f "$d0/$d.no" ]; then
+                                       msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
+                                       continue
+                               fi
+                               if $allow_pull; then
+                                       enter "$d0/$d" verbose
+                                       r=`git symbolic-ref HEAD`
+                                       r=${r#refs/heads/}
+                                       if git config branch.$r.remote >/dev/null 2>&1; then
+                                               if ! verbose git pull; then
+                                                       fix_upstream_rebase_mergefail || true
+                                                       check_mergeconflict "$d"
+                                                       $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
+                                                       read -r DUMMY
+                                               else
+                                                       fix_upstream_rebase_mergeok || true
+                                               fi
+                                       fi
+
+                                       cd "$d00"
+                                       checkself "$cmd" "$@"
+                                       cd "$d0/$d"
+                                       verbose git remote prune origin
+                                       cd "$d0"
+                               fi
+                       else
+                               if [ -d "$d0/$d" ]; then
+                                       if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
+                                               verbose rm -rf "$d0/$d"
+                                       else
+                                               echo "Note: $d0/$d will stay broken."
+                                               continue
+                                       fi
+                               fi
+                               verbose git clone "$url" "$d0/$d"
+                               enter "$d0/$d" verbose
+                               fix_git_config "$url" "$pushurl"
+                               if [ "$branch" != "master" ]; then
+                                       verbose git checkout --track -b "$branch" origin/"$branch"
+                               fi
+                               cd "$d0"
+                       fi
+               done
+               ;;
+       checkout|switch)
+               checkoutflags=
+               if [ x"$1" = x"-f" ]; then
+                       checkoutflags=-f
+                       shift
+               fi
+               remote=$1
+               branch=$2
+               if [ -z "$branch" ]; then
+                       case "$remote" in
+                               origin/*)
+                                       branch=${remote#origin/}
+                                       remote=origin
+                                       ;;
+                               *)
+                                       branch=$remote
+                                       remote=origin
+                                       ;;
+                       esac
+               fi
+               if [ -n "$checkoutflags" ]; then
+                       set -- -f "$@" # to make checkself work again
+               fi
+               exists=false
+               for d in $repos; do
+                       enter "$d0/$d" verbose
+                       b=$branch
+                       if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
+                               exists=true
+                               verbose git checkout $checkoutflags "$b"
+                       elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
+                               exists=true
+                               verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
+                       else
+                               b=`repobranch "$d"`
+                               if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
+                                       verbose git checkout $checkoutflags "$b"
+                               elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
+                                       verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
+                               else
+                                       $ECHO "WTF? Not even branch $b doesn't exist in $d"
+                                       exit 1
+                               fi
+                       fi
+                       cd "$d00"
+                       checkself "$cmd" "$@"
+                       cd "$d0"
+               done
+               if ! $exists; then
+                       $ECHO "The requested branch was not found in any repository."
+               fi
+               exec "$SELF" branch
+               ;;
+       branch)
+               remote=$1
+               branch=$2
+               srcbranch=$3
+               if [ -z "$branch" ]; then
+                       branch=$remote
+                       remote=origin
+               fi
+               if [ -z "$branch" ]; then
+                       for d in $repos; do
+                               enter "$d0/$d"
+                               r=`git symbolic-ref HEAD`
+                               r=${r#refs/heads/}
+                               $ECHO "$d is at $r"
+                               cd "$d0"
+                       done
+               else
+                       for d in $repos; do
+                               dv=`visible_repo_name "$d"`
+                               enter "$d0/$d" verbose
+                               if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
+                                       $ECHO "Already having this branch in $dv."
+                               else
+                                       if yesno "Branch in $dv?"; then
+                                               if [ -n "$srcbranch" ]; then
+                                                       b=$srcbranch
+                                               else
+                                                       b=origin/"`repobranch "$d"`"
+                                                       verbose git fetch origin || true
+                                               fi
+                                               # TODO do this without pushing
+                                               verbose git checkout -b "$branch" "$b"
+                                               verbose git config "branch.$branch.remote" "$remote"
+                                               verbose git config "branch.$branch.merge" "refs/heads/$branch"
+                                       fi
+                               fi
+                               cd "$d0"
+                       done
+                       "$SELF" branch
+               fi
+               ;;
+       branches)
+               for d in $repos; do
+                       cd "$d0/$d" # am in a pipe, shouldn't use enter
+                       git branch -r -v -v | cut -c 3- | sed "s/^(no branch)/(no_branch)/" | sed "s,^,$d ,"
+                       cd "$d0"
+               done | {
+                       branches_list=
+                       # branches_repos_*=
+                       while read -r d BRANCH REV TEXT; do
+                               if [ x"$BRANCH" = x"`repobranch "$d"`" ]; then
+                                       continue
+                               fi
+                               if [ x"$REV" = x"->" ]; then
+                                       continue
+                               fi
+                               BRANCH=${BRANCH#remotes/}
+                               ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
+                               branches_list="$branches_list $BRANCH" # TEH SORT MAKEZ IT UNIEQ
+                               eval "r=\$branches_repos_$ID"
+                               r="$r $d"
+                               eval "branches_repos_$ID=\$r"
+                       done
+                       $ECHO -n "$branches_list" | xargs -n 1 $ECHO | sort -u | while IFS= read -r BRANCH; do
+                               ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
+                               eval "r=\$branches_repos_$ID"
+                               printf "%-60s %s\n" "$BRANCH" "$r"
+                               #$ECHO "$BRANCH: $r"
+                       done
+               }
+               ;;
+       push|commit)
+               submit=$1
+               for d in $repos; do
+                       dv=`visible_repo_name "$d"`
+                       enter "$d0/$d" verbose
+                       r=`git symbolic-ref HEAD`
+                       r=${r#refs/heads/}
+                       diffdata=`git diff --color HEAD`
+                       if [ -n "$diffdata" ]; then
+                               # we have uncommitted changes
+                               if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
+                                       verbose git commit -a
+                               fi
+                       fi
+                       rem=`git config "branch.$r.remote" || $ECHO origin`
+                       bra=`git config "branch.$r.merge" || $ECHO "$r"`
+                       upstream="$rem/${bra#refs/heads/}"
+                       if ! git rev-parse "$upstream" >/dev/null 2>&1; then
+                               upstream="origin/`repobranch "$d"`"
+                       fi
+                       logdata=`git log --color "$upstream".."$r"`
+                       if [ -n "$logdata" ]; then
+                               if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
+                                       verbose git push "$rem" HEAD
+                               fi
+                       fi
+                       if [ x"$submit" = x"-s" ]; then
+                               case "$r" in
+                                       */*)
+                                               verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
+                                               ;;
+                               esac
+                       fi
+                       cd "$d0"
+               done
+               ;;
+       each|foreach)
+               keep_going=false
+               if [ x"$1" = x"-k" ]; then
+                       keep_going=true
+                       shift
+               fi
+               for d in $repos; do
+                       if verbose cd "$d0/$d"; then
+                               if $keep_going; then
+                                       verbose "$@" || true
+                               else
+                                       verbose "$@"
+                               fi
+                               cd "$d0"
+                       fi
+               done
+               ;;
+       clean)
+               "$SELF" fix_config
+               "$SELF" update -N
+               force=false
+               gotoupstream=false
+               fetchupstream=false
+               gotomaster=false
+               rmuntracked=false
+               killbranches=false
+               # usage:
+               #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
+               #   ./all clean --reclone
+               found=false
+               for X in "$@"; do
+                       if [ x"$X" = x"--reclone" ]; then
+                               force=true
+                               fetchupstream=true
+                               gotoupstream=true
+                               gotomaster=true
+                               rmuntracked=true
+                               killbranches=true
+                       elif [ x"$X" = x"-f" ]; then
+                               force=true
+                       elif [ x"$X" = x"-u" ]; then
+                               gotoupstream=true
+                       elif [ x"$X" = x"-U" ]; then
+                               gotoupstream=true
+                               fetchupstream=true
+                       elif [ x"$X" = x"-fu" ]; then
+                               force=true
+                               gotoupstream=true
+                       elif [ x"$X" = x"-fU" ]; then
+                               force=true
+                               gotoupstream=true
+                               fetchupstream=true
+                       elif [ x"$X" = x"-m" ]; then
+                               gotomaster=true
+                       elif [ x"$X" = x"-r" ]; then
+                               rmuntracked=true
+                       elif [ x"$X" = x"-D" ]; then
+                               killbranches=true
+                       elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
+                               msg ''
+                               msg "        _____"
+                               msg "    ,--'-\\P/\`\\  FFFFFFF"
+                               msg " __/_    B/,-.\\  FFFFFFF"
+                               msg " /  _\\  (//  O\\\\  FFFFFF"
+                               msg "| (O  \`) _\\._ _)\\  FFFUU"
+                               msg "| |___/.^d0~~\"\\  \\ UUUU"
+                               msg "|     |\`~'     \\ |  UUUU"
+                               msg "|     |    __,C>|| UUUU"
+                               msg "\\    /_ ,-/,-'   |  UUUU"
+                               msg " \\\\_ \\_>~'      /  UUUU-"
+                               msg ''
+                       else
+                               msg "Unknown arg: $X"
+                       fi
+                       found=true
+               done
+               if ! $found; then
+                       rmuntracked=true
+               fi
+               for d in $repos; do
+                       verbose cd "$d0/$d"
+                       if $gotoupstream; then
+                               if ! $force; then
+                                       msg "Must also use -f (delete local changes) when using -u"
+                                       exit 1
+                               fi
+                               if $gotomaster; then
+                                       if $fetchupstream; then
+                                               verbose git fetch origin
+                                               verbose git remote prune origin
+                                       fi
+                                       verbose git checkout -f "`repobranch "$d"`"
+                                       verbose git reset --hard origin/"`repobranch "$d"`"
+                               else
+                                       r=`git symbolic-ref HEAD`
+                                       r=${r#refs/heads/}
+                                       rem=`git config "branch.$r.remote" || $ECHO origin`
+                                       bra=`git config "branch.$r.merge" || $ECHO "$r"`
+                                       upstream="$rem/${bra#refs/heads/}"
+                                       if $fetchupstream; then
+                                               verbose git fetch "$rem"
+                                               verbose git remote prune "$rem"
+                                       fi
+                                       if ! git rev-parse "$upstream" >/dev/null 2>&1; then
+                                               upstream="origin/`repobranch "$d"`"
+                                       fi
+                                       verbose git reset --hard "$upstream"
+                               fi
+                       elif $gotomaster; then
+                               if $force; then
+                                       verbose git checkout -f "`repobranch "$d"`"
+                                       verbose git reset --hard
+                               else
+                                       verbose git checkout "`repobranch "$d"`"
+                               fi
+                       elif $force; then
+                               verbose git reset --hard
+                       fi
+                       if $rmuntracked; then
+                               case "$d" in
+                                       .)
+                                               verbose git clean -df || true
+                                               ;;
+                                       *)
+                                               verbose git clean -xdf || true
+                                               ;;
+                               esac
+                       fi
+                       if $killbranches; then
+                               git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
+                                       if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
+                                               verbose git branch -D "${B#refs/heads/}"
+                                       fi
+                               done
+                               git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
+                               git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch --track "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
+                       fi
+                       checkself "$cmd" "$@"
+               done
+               ;;
+       help)
+               $ECHO "  $SELF branch <branch>"
+               $ECHO "  $SELF branch <remote> <branch> [<srcbranch>]"
+               $ECHO "  $SELF branches"
+               $ECHO "  $SELF checkout|switch <branch>"
+               $ECHO "  $SELF checkout|switch <remote>/<branch>"
+               $ECHO "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
+               $ECHO "  $SELF clean --reclone"
+               $ECHO "  $SELF each|foreach [-k] command..."
+               $ECHO "  $SELF fix_upstream_rebase"
+               $ECHO "  $SELF keygen"
+               $ECHO "  $SELF push|commit [-s]"
+               $ECHO "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
+               handled=false
+               ;;
+       *)
+               handled=false
+               ;;
+esac
diff --git a/misc/tools/all/release.subr b/misc/tools/all/release.subr
new file mode 100644 (file)
index 0000000..b84d57b
--- /dev/null
@@ -0,0 +1,615 @@
+release_common()
+{
+       export LC_ALL=C
+
+       release_args="$cmd $*"
+       msg "*** $release_args: start"
+       release_starttime=`date +%s`
+       release_end()
+       {
+               release_endtime=`date +%s`
+               release_deltatime=$(($release_endtime - $release_starttime))
+               msg "*** $release_args: $release_deltatime seconds"
+       }
+       trap release_end EXIT
+       release_tempstarttime=$release_starttime
+       release_timereport()
+       {
+               release_endtime=`date +%s` # RELEASE NOW!!!
+               if [ -n "$*" ]; then
+                       release_deltatime=$(($release_endtime - $release_tempstarttime))
+                       msg "**** $release_args: $*: $release_deltatime seconds"
+               fi
+               release_tempstarttime=$release_endtime
+       }
+       release_git_extract_dir()
+       {
+               release_src=$1; shift
+               release_dst=$1; shift
+               # try to create a hardlink
+               if ln -f "$release_src/.git/HEAD" "$release_dst/.hardlink-test"; then
+                       rm -f "$release_dst/.hardlink-test"
+                       {
+                               verbose cd "$release_src"
+                               git ls-files HEAD -- "$@"
+                       } | {
+                               while IFS= read -r F; do
+                                       case "$F" in */*) mkdir -p "$release_dst/${F%/*}" ;; esac
+                                       verbose ln -f "$release_src/$F" "$release_dst/$F"
+                               done
+                       }
+               else
+                       {
+                               verbose cd "$release_src"
+                               verbose git archive --format=tar HEAD -- "$@"
+                       } | {
+                               verbose cd "$release_dst"
+                               verbose tar xvf -
+                       }
+               fi
+       }
+
+       mkzipr()
+       {
+               archive=$1; shift
+               case "$RELEASETYPE" in
+                       release)
+                               sevenzipflags=-mx=9
+                               zipflags=-9
+                               ;;
+                       *)
+                               sevenzipflags=-mx=1
+                               zipflags=-1
+                               ;;
+               esac
+               find "$@" -exec touch -d "2001-01-01 01:01:01 +0000" {} \+ # ugly hack to make the pk3 files rsync-friendly
+               ziplist=`mktemp`
+               find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
+               7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
+               zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
+               rm -f "$ziplist"
+       }
+
+       mkzip()
+       {
+               archive=$1; shift
+               case "$RELEASETYPE" in
+                       release)
+                               sevenzipflags=-mx=9
+                               zipflags=-9
+                               ;;
+                       *)
+                               sevenzipflags=-mx=1
+                               zipflags=-1
+                               ;;
+               esac
+               ziplist=`mktemp`
+               find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
+               7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
+               zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
+               rm -f "$ziplist"
+       }
+
+       mkzip0()
+       {
+               archive=$1; shift
+               zip -0ry "$archive" "$@"
+       }
+}
+
+handled=true
+case "$cmd" in
+       # release building goes here
+       release-prepare)
+               release_common
+               #"$SELF" each git clean -fxd
+               case "$RELEASETYPE" in
+                       '')
+                               $ECHO >&2 -n "$ESC[2J$ESC[H"
+                               msg ""
+                               msg ""
+                               msg ""
+                               msg ""
+                               msg ""
+                               msg ""
+                               msg "        +---------------------------------------------------------.---+"
+                               msg "        | NOTE                                                    | X |"
+                               msg "        +---------------------------------------------------------^---+"
+                               msg "        |   ____                                                      |"
+                               msg "        |  /    \  This is the official release build system.         |"
+                               msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
+                               msg "        | | STOP | you are not supposed to use this script and should |"
+                               msg "        | |      | instead use ./all compile to compile the engine    |"
+                               msg "        |  \____/  and game code.                                     |"
+                               msg "        |                                                             |"
+                               msg "        |                      [ I understand ]                       |"
+                               msg "        +-------------------------------------------------------------+"
+                               sleep 10
+                               # A LOT of build infrastructure is required:
+                               # - vorbis-tools
+                               # - ImageMagick
+                               # - .ssh/config must be configured so the following
+                               #   host names are reachable and have a compile
+                               #   infrastructure set up:
+                               #   - xonotic-build-linux32 (with gcc on x86)
+                               #   - xonotic-build-linux64 (with gcc on x86_64)
+                               #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
+                               #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
+                               #     and x86_64-w64-mingw32-g++)
+                               #   - xonotic-build-osx (with Xcode and SDL.framework)
+                               # - AMD Compressonator installed in WINE
+                               # - ResEdit installed in WINE
+                               # - a lot of other requirements you will figure out
+                               #   while reading the error messages
+                               # - environment variable RELEASETYPE set
+                               # - optionally, environment variable RELEASEDATE set
+                               #   (YYYYMMDD)
+                               exit 1
+                               ;;
+                       release)
+                               msg "Building a FINISHED RELEASE"
+                               ;;
+                       *)
+                               msg "Building a $RELEASETYPE"
+                               ;;
+               esac
+               verbose rm -rf Xonotic Xonotic*.zip
+               verbose mkdir -p Xonotic
+               if [ -n "$RELEASEDATE" ]; then
+                       verbose $ECHO "$RELEASEDATE" > Xonotic/stamp.txt
+               else
+                       verbose date +%Y%m%d > Xonotic/stamp.txt
+               fi
+               release_git_extract_dir "." "Xonotic" Docs misc server xonotic-linux-glx.sh xonotic-linux-sdl.sh misc/buildfiles key_0.d0pk COPYING GPL-2 GPL-3
+               (
+                       verbose cd Xonotic
+                       verbose mkdir data fteqcc source source/darkplaces source/fteqcc source/d0_blind_id mapping
+                       verbose rm -rf misc/builddeps
+                       verbose mv misc/buildfiles/win32 bin32 || true
+                       verbose mv bin32/SDL.dll . || true
+                       verbose mv misc/buildfiles/win64 bin64 || true
+                       verbose mv misc/buildfiles/osx/* . || true
+                       verbose rm -rf misc/buildfiles
+                       verbose rm -rf misc/pki
+               )
+               release_git_extract_dir "darkplaces" "Xonotic/source/darkplaces" .
+               release_git_extract_dir "fteqcc" "Xonotic/source/fteqcc" .
+               release_git_extract_dir "data/xonotic-data.pk3dir" "Xonotic/source" qcsrc Makefile
+               release_git_extract_dir "d0_blind_id" "Xonotic/source/d0_blind_id" .
+               (
+                       verbose cd Xonotic/source/d0_blind_id
+                       verbose sh autogen.sh
+               )
+               rm -f Xonotic/key_15.d0pk
+               {
+                       verbose cd Xonotic/mapping
+                       verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20120114.tar.bz2
+                       verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20120114-win32-7z.exe
+                       for X in *-7z.exe; do
+                               7za x "$X"
+                               rm -f "$X"
+                       done
+                       # TODO possibly include other tools?
+               }
+               ;;
+       release-compile-run)
+               release_common
+               host=$1
+               buildpath=$2
+               maketargets=$3
+               makeflags=$4
+               srcdir=$5
+               depsdir=$6
+               targetfiles=$7
+               set -x
+               if [ -n "$targetfiles" ]; then
+                       case " $HOSTS_THAT_ARE_DISABLED " in
+                               *\ $host\ *)
+                                       exit
+                                       ;;
+                       esac
+                       case " $HOSTS_THAT_ARE_MYSELF " in
+                               *\ $host\ *)
+                                       verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
+                                       verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
+                                       verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
+                                       verbose eval make -C "$buildpath" clean $maketargets $makeflags
+                                       for f in $targetfiles; do
+                                               verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
+                                       done
+                                       ;;
+                               *)
+                                       verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
+                                       verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
+                                       verbose ssh "$host" "[ -f /etc/profile ] && . /etc/profile; [ -f ~/.profile ] && . ~/.profile; export LC_ALL=C; ln -snf $buildpath.deps $buildpath/.deps && cd $buildpath && nice -`nice` make clean $maketargets $makeflags"
+                                       for f in $targetfiles; do
+                                               verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
+                                       done
+                                       ;;
+                       esac
+                       # now rebrand the binaries...
+                       for f in $targetfiles; do
+                               #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
+                               case "${f##*:}" in
+                                       Xonotic/xonotic*.exe)
+                                               verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
+                                               ;;
+                               esac
+                       done
+               fi
+               ;;
+       release-compile)
+               release_common
+               suffix=$1
+               makeflags=$2
+               fteqcc_maketargets=$3
+               fteqcc_files=$4
+               darkplaces_maketargets=$5
+               darkplaces_files=$6
+               host=xonotic-build-$suffix
+               verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
+               verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
+               ;;
+       release-engine-win32)
+               release_common
+               verbose "$SELF" release-compile win32 \
+                       'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-gcc -march=i686 -g1 -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' \
+                       win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
+                       '' ''
+               verbose "$SELF" release-compile win32 \
+                       'STRIP=: DP_MAKE_TARGET=mingw CC="i586-mingw32msvc-g++ -g1 -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=1' \
+                       '' '' \
+                       release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
+               ;;
+       release-engine-win64)
+               release_common
+               verbose "$SELF" release-compile win64 \
+                       'STRIP=: DP_MAKE_TARGET=mingw CC="amd64-mingw32msvc-gcc -g1 -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' \
+                       win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
+                       'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
+               verbose "$SELF" release-compile win64 \
+                       'STRIP=: DP_MAKE_TARGET=mingw CC="x86_64-w64-mingw32-g++ -g1 -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=1' \
+                       '' '' \
+                       cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
+               ;;
+       release-engine-osx)
+               release_common
+               # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
+               verbose "$SELF" release-compile osx \
+                       'STRIP=: CC="gcc -g1 -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"' \
+                       all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
+                       'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
+               ;;
+       release-engine-linux32)
+               release_common
+               verbose "$SELF" release-compile linux32 \
+                       'STRIP=: CC="gcc -m32 -march=i686 -g1 -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' \
+                       all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
+                       release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
+               ;;
+       release-engine-linux64)
+               release_common
+               verbose "$SELF" release-compile linux64 \
+                       'STRIP=: CC="gcc -m64 -g1 -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' \
+                       all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
+                       release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
+               ;;
+       release-engine)
+               release_common
+               verbose "$SELF" release-engine-linux32 &
+               verbose "$SELF" release-engine-linux64 &
+               verbose "$SELF" release-engine-win32 &
+               verbose "$SELF" release-engine-win64 &
+               verbose "$SELF" release-engine-osx &
+               wait %1
+               wait %2
+               wait %3
+               wait %4
+               wait %5
+               wait
+               ;;
+       release-maps)
+               release_common
+               verbose "$SELF" update-maps
+               ;;
+       release-qc)
+               release_common
+               verbose env GIT_DIR="$d0/data/xonotic-data.pk3dir/.git" make -C Xonotic/source FTEQCC="$d0/Xonotic/fteqcc/fteqcc.linux32" XON_BUILDSYSTEM=1 clean all
+               verbose rm -f Xonotic/source/qcsrc/*/fteqcc.log
+               ;;
+       release-buildpk3-transform-raw)
+               release_common
+               dir=$1
+               ;;
+       release-buildpk3-transform-normal)
+               release_common
+               dir=$1
+               verbose cd "$dir"
+               # texture: convert to jpeg and dds
+               verbose export do_jpeg=true
+               verbose export jpeg_qual_rgb=97
+               verbose export jpeg_qual_a=99
+               verbose export do_dds=false
+               verbose export do_ogg=true
+               verbose export ogg_ogg=false
+               verbose export del_src=true
+               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
+               ;;
+       release-buildpk3-transform-normaldds)
+               release_common
+               dir=$1
+               verbose cd "$dir"
+               # texture: convert to jpeg and dds
+               # music: reduce bitrate
+               verbose export do_jpeg=false
+               verbose export do_jpeg_if_not_dds=true
+               verbose export jpeg_qual_rgb=95
+               verbose export jpeg_qual_a=99
+               verbose export do_dds=true
+               verbose export dds_flags=
+               verbose export do_ogg=true
+               verbose export ogg_ogg=false
+               verbose export del_src=true
+               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
+               ;;
+       release-buildpk3-transform-low)
+               release_common
+               dir=$1
+               verbose cd "$dir"
+               # texture: convert to jpeg and dds
+               # music: reduce bitrate
+               verbose export do_jpeg=true
+               verbose export jpeg_qual_rgb=80
+               verbose export jpeg_qual_a=97
+               verbose export do_dds=false
+               verbose export do_ogg=true
+               verbose export ogg_qual=1
+               verbose export del_src=true
+               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
+               ;;
+       release-buildpk3-transform-lowdds)
+               release_common
+               dir=$1
+               verbose cd "$dir"
+               # texture: convert to jpeg and dds
+               # music: reduce bitrate
+               verbose export do_jpeg=false
+               verbose export do_jpeg_if_not_dds=true
+               verbose export jpeg_qual_rgb=80
+               verbose export jpeg_qual_a=99
+               verbose export do_dds=true
+               verbose export dds_flags=
+               verbose export do_ogg=true
+               verbose export ogg_qual=1
+               verbose export del_src=true
+               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
+               ;;
+       release-buildpk3-transform-mapping)
+               release_common
+               dir=$1
+               verbose cd "$dir"
+               # remove stuff radiant has no use for
+               verbose find . -name \*_norm.\* -exec rm -f {} \;
+               verbose find . -name \*_bump.\* -exec rm -f {} \;
+               verbose find . -name \*_glow.\* -exec rm -f {} \;
+               verbose find . -name \*_gloss.\* -exec rm -f {} \;
+               verbose find . -name \*_pants.\* -exec rm -f {} \;
+               verbose find . -name \*_shirt.\* -exec rm -f {} \;
+               verbose find . -name \*_reflect.\* -exec rm -f {} \;
+               verbose find . -not \( -name \*.tga -o -name \*.png -o -name \*.jpg \) -exec rm -f {} \;
+               # texture: convert to jpeg and dds
+               # music: reduce bitrate
+               verbose export do_jpeg=true
+               verbose export jpeg_qual_rgb=80
+               verbose export jpeg_qual_a=97
+               verbose export do_dds=false
+               verbose export do_ogg=true
+               verbose export ogg_qual=1
+               verbose export del_src=true
+               find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
+               ;;
+       release-buildpk3)
+               release_common
+               src=$1
+               dst=$2
+               transform=$3
+               case "$dst" in
+                       /*)
+                               ;;
+                       */)
+                               dst="$PWD/$dst"
+                               ;;
+               esac
+               release_timereport
+               verbose rm -rf Xonotic/temp
+               release_timereport "deleted temp directory"
+               verbose mkdir -p Xonotic/temp
+               release_git_extract_dir "$src" "Xonotic/temp" .
+               release_timereport "extracted data"
+               verbose cd Xonotic/temp
+               if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
+                       verbose cp ../source/progs.dat .
+                       verbose cp ../source/csprogs.dat .
+                       verbose cp ../source/menu.dat .
+                       verbose rm -rf qcsrc
+                       gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
+                       major=$(($gv / 10000))
+                       minor=$((($gv / 100) - ($major * 100)))
+                       patch=$(($gv - ($major * 10000) - ($minor * 100)))
+                       versionstr="$major.$minor.$patch"
+                       case "$RELEASETYPE" in
+                               release)
+                                       ;;
+                               *)
+                                       versionstr="$versionstr$RELEASETYPE"
+                                       ;;
+                       esac
+                       if [ $gv -lt 9900 ]; then
+                               # pre-1.0: compatible with any other pre-1.0
+                               verbose sed "
+                                       s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
+                                       s/^gameversion_min [0-9]*/gameversion_min     0/;
+                                       s/^gameversion_max [0-9]*/gameversion_max  9999/;
+                               " < defaultXonotic.cfg > defaultXonotic.cfg.new
+                       else
+                               # >= 1.0
+                               verbose sed "
+                                       s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
+                                       s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
+                                       s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
+                               " < defaultXonotic.cfg > defaultXonotic.cfg.new
+                       fi
+                       mv defaultXonotic.cfg.new defaultXonotic.cfg
+                       case "$RELEASETYPE" in
+                               release)
+                                       echo "" >> defaultXonotic.cfg
+                                       echo "// nicer menu" >> defaultXonotic.cfg
+                                       echo "set menu_watermark \"\"" >> defaultXonotic.cfg
+                                       ;;
+                       esac
+                       (
+                               verbose cd gfx/menu/luminos
+                               verbose rm -f background_l2.tga background_ingame_l2.tga
+                               verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
+                               verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
+                               verbose rm background_l2.svg
+                       )
+               fi
+               if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
+                       for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
+                               if [ -f "$X" ]; then
+                                       verbose unzip "$X"
+                                       verbose rm -f maps/*.log maps/*.irc maps/*.lin
+                               fi
+                       done
+               fi
+               verbose export git_src_repo="$d0/$src" # skip hash-object
+               release_timereport "processed data"
+               verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
+               release_timereport "transformed data"
+               find . -type f -size +4k | verbose "$d0"/misc/tools/symlink-deduplicate.sh
+               release_timereport "deduplicated data"
+               verbose mkzipr "../../$dst" *
+               release_timereport "zipped data"
+               verbose cd ../..
+               verbose rm -rf Xonotic/temp
+               release_timereport "deleted temp directory again"
+               ;;
+       release-buildpk3s)
+               release_common
+               stamp=`cat Xonotic/stamp.txt`
+               src=$1
+               shift
+               dst=${src%.pk3dir}
+               case "$dst" in
+                       data/xonotic-*)
+                               dst="data/xonotic-$stamp-${dst#data/xonotic-}"
+                               ;;
+                       *)
+                               dst="$dst-$stamp"
+                               ;;
+               esac
+               while [ "$#" -gt 1 ]; do
+                       verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
+                       shift
+                       shift
+               done
+               ;;
+       release-pack)
+               release_common
+               verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir                  raw ''
+               verbose "$SELF" release-buildpk3s data/font-xolonium.pk3dir                     raw ''
+               verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal '-high'        low '-low' normaldds ''
+               verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal '-high'        low '-low' normaldds '' mapping '-mapping'
+               verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                     raw '' low '-low'
+               verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir  normal '-high'                   normaldds ''
+               ;;
+       release-pack-needsx11)
+               release_common
+               case "$DISPLAY" in
+                       '')
+                               verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
+                               ;;
+                       *)
+                               verbose "$SELF" release-pack
+                               ;;
+               esac
+               ;;
+       release-zip)
+               release_common
+               stamp=`cat Xonotic/stamp.txt`
+               # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
+               chmod a-x Xonotic/*.exe Xonotic/*.dll || true
+               # let's pass crypto import laws of some nasty countries
+               crypto_libs=`find Xonotic -name \*d0_rijndael\*.so -o -name \*d0_rijndael\*.dylib -o -name \*d0_rijndael\*.dll -o -name \*d0_rijndael\*.c`
+               if [ -n "$crypto_libs" ]; then
+                       verbose mkzip Xonotic-$stamp-crypto.zip \
+                               $crypto_libs \
+                               Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
+                       rm -f $crypto_libs
+               fi
+               # build the archives
+               verbose mkzip Xonotic-$stamp-enginesource.zip \
+                       Xonotic/source/darkplaces/ \
+                       Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
+               verbose cp Xonotic-$stamp-enginesource.zip Xonotic-$stamp-engine.zip
+               verbose mkzip Xonotic-$stamp-engine.zip \
+                       Xonotic/*.dll \
+                       Xonotic/bin32/*.dll \
+                       Xonotic/bin64/*.dll \
+                       Xonotic/*.app \
+                       Xonotic/xonotic-* \
+                       Xonotic/xonotic.exe
+               verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
+               verbose mkzip Xonotic-$stamp-common.zip \
+                       Xonotic/source/fteqcc/ \
+                       Xonotic/source/qcsrc/ \
+                       Xonotic/Docs \
+                       Xonotic/misc \
+                       Xonotic/fteqcc \
+                       Xonotic/server \
+                       Xonotic/key_0.d0pk \
+                       Xonotic/data/font-nimbussansl-$stamp.pk3 \
+                       Xonotic/data/font-xolonium-$stamp.pk3
+               verbose cp Xonotic-$stamp-enginesource.zip Xonotic-$stamp-source.zip
+               verbose mkzip Xonotic-$stamp-source.zip \
+                       Xonotic/source/fteqcc/ \
+                       Xonotic/source/qcsrc/ \
+                       Xonotic/misc/logos
+               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
+               verbose mkzip0 Xonotic-$stamp.zip \
+                       Xonotic/data/xonotic-$stamp-data.pk3 \
+                       Xonotic/data/xonotic-$stamp-maps.pk3 \
+                       Xonotic/data/xonotic-$stamp-music.pk3 \
+                       Xonotic/data/xonotic-$stamp-nexcompat.pk3
+               verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
+               verbose mkzip0 Xonotic-$stamp-low.zip \
+                       Xonotic/data/xonotic-$stamp-data-low.pk3 \
+                       Xonotic/data/xonotic-$stamp-maps-low.pk3 \
+                       Xonotic/data/xonotic-$stamp-music-low.pk3
+               verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
+               verbose mkzip Xonotic-$stamp-high.zip \
+                       Xonotic/mapping
+               verbose mkzip0 Xonotic-$stamp-high.zip \
+                       Xonotic/data/xonotic-$stamp-data-high.pk3 \
+                       Xonotic/data/xonotic-$stamp-maps-high.pk3 \
+                       Xonotic/data/xonotic-$stamp-music.pk3 \
+                       Xonotic/data/xonotic-$stamp-nexcompat-high.pk3
+               verbose mkzip Xonotic-$stamp-mappingsupport.zip \
+                       Xonotic/mapping
+               verbose mkzip0 Xonotic-$stamp-mappingsupport.zip \
+                       Xonotic/data/xonotic-$stamp-maps-mapping.pk3
+               ;;
+       release)
+               release_common
+               verbose "$SELF" release-prepare
+               verbose "$SELF" release-maps
+               verbose "$SELF" release-engine
+               verbose "$SELF" release-qc
+               verbose "$SELF" release-pack-needsx11
+               verbose "$SELF" release-zip
+               ;;
+       *)
+               handled=false
+               ;;
+esac
diff --git a/misc/tools/all/xonotic.subr b/misc/tools/all/xonotic.subr
new file mode 100644 (file)
index 0000000..c8b7f8f
--- /dev/null
@@ -0,0 +1,311 @@
+handled=true
+case "$cmd" in
+       update-maps)
+               misc/tools/xonotic-map-compiler-autobuild download
+               ;;
+       compile)
+               cleand0=false
+               cleandp=false
+               cleanqcc=false
+               cleanqc=false
+               compiled0=false
+               debug=debug
+               snowleopardhack=false
+               if [ -z "$CC" ]; then
+                       export CC="gcc"
+               fi
+               export CC="$CC -DSUPPORTIPV6"
+               while :; do
+                       case "$1" in
+                               -0)
+                                       compiled0=true
+                                       shift
+                                       ;;
+                               -c)
+                                       cleand0=true
+                                       cleandp=true
+                                       cleanqcc=true
+                                       cleanqc=true
+                                       shift
+                                       ;;
+                               -r|-p)
+                                       case "$1" in
+                                               -p)
+                                                       debug=profile
+                                                       ;;
+                                               -r)
+                                                       debug=release
+                                                       ;;
+                                       esac
+                                       export CC="$CC -g"
+                                       case "`$CC -dumpversion`" in
+                                               [5-9]*|[1-9][0-9]*|4.[3-9]*|4.[1-9][0-9]*)
+                                                       # gcc 4.3 or higher
+                                                       # -march=native is broken < 4.3
+                                                       if $CC -mtune=native -march=native misc/tools/conftest.c -o conftest >/dev/null 2>&1; then
+                                                               export CC="$CC -mtune=native -march=native"
+                                                       fi
+                                                       ;;
+                                       esac
+                                       if [ -n "$WE_HATE_OUR_USERS" ]; then
+                                               export CC="$CC -fno-common"
+                                       fi
+                                       shift
+                                       ;;
+                               *)
+                                       break
+                                       ;;
+                       esac
+               done
+               if [ -n "$WE_HATE_OUR_USERS" ]; then
+                       TARGETS="sv-$debug cl-$debug"
+               elif [ x"`uname`" = x"Darwin" ]; then
+                       case "`uname -r`" in
+                               ?.*)
+                                       TARGETS="sv-$debug cl-$debug sdl-$debug"
+                                       ;;
+                               *)
+                                       # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
+                                       snowleopardhack=true
+                                       TARGETS="sv-$debug sdl-$debug"
+                                       ;;
+                       esac
+                       export CC="$CC -fno-reorder-blocks -I$PWD/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks/SDL.framework/Headers -F$PWD/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
+               else
+                       TARGETS="sv-$debug cl-$debug sdl-$debug"
+               fi
+               if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
+                       # if we give the command make the arg "", it will surely fail (invalid filename),
+                       # so better handle it as an empty client option
+                       BAD_TARGETS=" "
+                       shift
+               elif [ -n "$1" ]; then
+                       BAD_TARGETS=
+                       TARGETS_SAVE=$TARGETS
+                       TARGETS=
+                       for X in $1; do
+                               case "$X" in
+                                       sdl)
+                                               TARGETS="$TARGETS sdl-debug"
+                                               ;;
+                                       agl)
+                                               TARGETS="$TARGETS cl-debug"
+                                               if $snowleopardhack; then
+                                                       export CC="$CC -arch i386"
+                                               fi
+                                               ;;
+                                       glx|wgl)
+                                               TARGETS="$TARGETS cl-debug"
+                                               ;;
+                                       dedicated)
+                                               TARGETS="$TARGETS sv-debug"
+                                               ;;
+                                       *)
+                                               BAD_TARGETS="$BAD_TARGETS $X"
+                                               ;;
+                               esac
+                       done
+                       if [ -n "$TARGETS" ]; then # at least a valid client
+                               shift
+                       else # no valid client, let's assume this option is not meant to be a client then
+                               TARGETS=$TARGETS_SAVE
+                               BAD_TARGETS=
+                       fi
+               fi
+               if [ -z "$MAKEFLAGS" ]; then
+                       if [ -f /proc/cpuinfo ]; then
+                               ncpus=$((`grep -c '^processor   :' /proc/cpuinfo || true`+0))
+                               if [ $ncpus -gt 1 ]; then
+                                       MAKEFLAGS=-j$ncpus
+                               fi
+                       fi
+                       if [ -n "$WE_HATE_OUR_USERS" ]; then
+                               MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
+                       fi
+               fi
+
+               
+               if ! verbose $CC misc/tools/conftest.c -o conftest; then
+                       msg ""
+                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+                       msg "~~~~~~~~~~ COMPILER ~~~~~~~~~~"
+                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+                       msg "~~~~~~~~~~~~~~_...._~~~~~~~~~~"
+                       msg "~~~~~~~~~~~,-'     \\\`-._~~~~~~"
+                       msg "~~~~~~~~~~/     --. ><  \\~~~~~"
+                       msg "~~~~~~~~~/      (*)> -<: \\~~~~"
+                       msg "~~~~~~~~~(     ^~-'  (*) )~~~~"
+                       msg "~~~~~~~~~\\        ^+-_/  |~~~~"
+                       msg "~~~~~~~~~~\\       {vvv}  |~~~~"
+                       msg "~~~~~~~~~~,\\    , {^^^},/~~~~~"
+                       msg "~~~~~~~~,/  \`---.....-'~~W~~~~"
+                       msg "~~~~~~,/   \\_____/_\\_W~~/~~~~~"
+                       msg "~~~~~/          /~~~\\__/~~~~~~"
+                       msg "~~~~/          /~~~~~~~~~~~~~~"
+                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+                       msg "~~~~~~~ Y U NO COMPILE ~~~~~~~"
+                       msg "~~~~~~~~~~~~ CODE ~~~~~~~~~~~~"
+                       msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
+                       msg ""
+                       exit 1
+               fi
+               rm -f conftest
+
+               verbose cd "$d0/d0_blind_id"
+               if ! $compiled0; then
+                       # compilation of crypto library failed
+                       # use binaries then, if we can...
+                       mkdir -p .libs
+                       if [ -n "$WE_HATE_OUR_USERS" ]; then
+                               verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
+                               verbose cp "$d0/misc/buildfiles/win32/libd0_rijndael"-* .libs/
+                               verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
+                       else
+                               case "`uname`" in
+                                       Linux)
+                                               case `uname -m` in
+                                                       x86_64)
+                                                               #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
+                                                               #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_rijndael".* .libs/
+                                                               #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
+                                                               MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
+                                                               ;;
+                                                       *86)
+                                                               #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
+                                                               #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_rijndael".* .libs/
+                                                               #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
+                                                               MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
+                                                               ;;
+                                                       *)
+                                                               compiled0=true
+                                                               ;;
+                                               esac
+                                               ;;
+                                       Darwin)
+                                               verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
+                                               verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael".* .libs/
+                                               ;;
+                                       *)
+                                               compiled0=true
+                                               ;;
+                               esac
+                       fi
+               fi
+               if $compiled0; then
+                       if $cleand0; then
+                               if [ -f Makefile ]; then
+                                       verbose make $MAKEFLAGS distclean
+                               fi
+                       fi
+                       if ! [ -f Makefile ]; then
+                               verbose sh autogen.sh
+                               verbose ./configure
+                       fi
+                       verbose make $MAKEFLAGS
+               fi
+
+               verbose cd "$d0/fteqcc"
+               if $cleanqcc; then
+                       verbose make $MAKEFLAGS clean
+               fi
+               verbose make $MAKEFLAGS
+
+               verbose cd "$d0/data/xonotic-data.pk3dir"
+               if $cleanqc; then
+                       verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
+               fi
+               verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
+               # 4 levels up: data, xonotic-data, qcsrc, server
+
+               verbose cd "$d0/darkplaces"
+               if [ x"$BAD_TARGETS" = x" " ]; then
+                       $ECHO "Warning: invalid empty client, default clients will be used."
+               fi
+               if $cleandp; then
+                       verbose make $MAKEFLAGS clean
+               fi
+               for T in $TARGETS; do
+                       verbose make $MAKEFLAGS STRIP=: "$@" "$T"
+               done
+               for T in $BAD_TARGETS; do
+                       $ECHO "Warning: discarded invalid client $T."
+               done
+
+               verbose "$SELF" update-maps
+               ;;
+       run)
+               if [ -n "$WE_HATE_OUR_USERS" ]; then
+                       client=
+                       export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
+               elif [ x"`uname`" = x"Darwin" ]; then
+                       export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS:$d0/d0_blind_id/.libs"
+                       export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
+                       client=-sdl
+               else
+                       export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
+                       client=-sdl
+               fi
+               case "$1" in
+                       sdl|glx|agl|dedicated)
+                               client=-$1
+                               shift
+                               ;;
+                       wgl)
+                               client=
+                               shift
+                               ;;
+               esac
+               if ! [ -x "darkplaces/darkplaces$client" ]; then
+                       if [ -x "darkplaces/darkplaces$client.exe" ]; then
+                               client=$client.exe
+                       else
+                               $ECHO "Client darkplaces/darkplaces$client not found, aborting"
+                               exit 1
+                       fi
+               fi
+               set -- "darkplaces/darkplaces$client" -xonotic "$@"
+
+               # if pulseaudio is running: USE IT
+               if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
+                       if ps -C pulseaudio >/dev/null; then
+                               if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
+                                       export SDL_AUDIODRIVER=pulse
+                               fi
+                       fi
+               fi
+
+               binary=$1
+
+               if [ x"$USE_GDB" = x"yes" ]; then
+                       set -- gdb --args "$@"
+               elif [ x"$USE_GDB" = x"core" ] && which gdb >/dev/null 2>&1; then
+                       set -- gdb --batch -x savecore.gdb --args "$@"
+               elif which catchsegv >/dev/null 2>&1; then
+                       set -- catchsegv "$@"
+               fi
+               rm -f xonotic.core
+               "$@" || true
+               if [ -f xonotic.core ]; then
+                       if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
+                               gdb "$binary" xonotic.core
+                       #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
+                       #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
+                       #       # somehow send it
+                       #       rm -f xonotic.core.tar.gz
+                       else
+                               $ECHO "The core dump can be examined later by"
+                               $ECHO "  gdb $binary xonotic.core"
+                       fi
+                       exit 1
+               fi
+               ;;
+       help)
+               $ECHO "  $SELF compile [-c] [-r|-p] [-0] [sdl|glx|wgl|agl|dedicated]"
+               $ECHO "  $SELF update-maps"
+               $ECHO "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
+               handled=false
+               ;;
+       *)
+               handled=false
+               ;;
+esac