]> git.xonotic.org Git - xonotic/xonotic.git/blob - all
detect broken clones and delete them
[xonotic/xonotic.git] / all
1 #!/bin/sh
2 # vim: filetype=zsh
3
4 set -e
5 if [ -n "$ZSH_VERSION" ]; then
6         setopt SH_WORD_SPLIT
7 fi
8 if [ -z "$ECHO" ]; then
9         if echo "\\\\" | grep .. >/dev/null; then
10                 ECHO=echo
11         else
12                 ECHO=`which echo`
13         fi
14 fi
15
16 # I use this in EVERY shell script ;)
17 LF="
18 "
19 ESC="\e"
20
21 d00=`pwd`
22 while ! [ -f ./all ]; do
23         if [ x"`pwd`" = x"/" ]; then
24                 $ECHO "Cannot find myself."
25                 $ECHO "Please run this script with the working directory inside a Xonotic checkout."
26                 exit 1
27         fi
28         cd ..
29 done
30 export d0=`pwd`
31 SELF="$d0/all"
32
33 # If we are on WINDOWS:
34 case "$0" in
35         all|*/all)
36                 case "`uname`" in
37                         MINGW*|Win*)
38                                 # Windows hates users. So this script has to copy itself elsewhere first...
39                                 cp "$SELF" ../all.xonotic.sh
40                                 export WE_HATE_OUR_USERS=1
41                                 exec ../all.xonotic.sh "$@"
42                                 ;;
43                 esac
44                 ;;
45 esac
46
47 msg()
48 {
49         $ECHO >&2 "$ESC""[1m$*$ESC""[m"
50 }
51
52 self=`git hash-object "$SELF"`
53 checkself()
54 {
55         self_new=`git hash-object "$SELF"`
56         if [ x"$self" != x"$self_new" ]; then
57                 msg "./all has changed."
58                 if [ -z "$XONOTIC_FORBID_RERUN_ALL" ]; then
59                         msg "Rerunning the requested operation to make sure."
60                         export XONOTIC_FORBID_RERUN_ALL=1
61                         exec "$SELF" "$@"
62                 else
63                         msg "Please try $SELF update, and then retry your requested operation."
64                         exit 1
65                 fi
66         fi
67         return 0
68 }
69
70 verbose()
71 {
72         msg "+ $*"
73         "$@"
74 }
75
76 visible_repo_name()
77 {
78         case "$1" in
79                 .)
80                         $ECHO "the root directory"
81                         ;;
82                 *)
83                         $ECHO "\"$1\""
84                         ;;
85         esac
86 }
87
88 check_mergeconflict()
89 {
90         if git ls-files -u | grep ' 1   '; then
91                 $ECHO
92                 $ECHO "MERGE CONFLICT."
93                 $ECHO "change into the \"$1\" project directory, and then:"
94                 $ECHO "- edit the files mentioned above with your favorite editor,"
95                 $ECHO "  and fix the conflicts (marked with <<<<<<< blocks)"
96                 $ECHO "- for binary files, you can select the files using"
97                 $ECHO "  git checkout --ours or git checkout --theirs"
98                 $ECHO "- when done with a file, 'git add' the file"
99                 $ECHO "- when done, 'git commit'"
100                 $ECHO
101                 exit 1
102         fi
103 }
104
105 yesno()
106 {
107         yesno=
108         while [ x"$yesno" != x"y" -a x"$yesno" != x"n" ]; do
109                 eval "$2"
110                 $ECHO "$1"
111                 if ! IFS= read -r yesno; then
112                         yesno=n
113                         break
114                 fi
115         done
116         [ x"$yesno" = x"y" ]
117 }
118
119 enter()
120 {
121         $2 cd "$1" || exit 1
122         check_mergeconflict "$1"
123 }
124
125 repos_urls="
126 .                             |                                                   | master         |
127 data/xonotic-data.pk3dir      |                                                   | master         |
128 data/xonotic-music.pk3dir     |                                                   | master         |
129 data/xonotic-nexcompat.pk3dir |                                                   | master         | no
130 darkplaces                    |                                                   | div0-stable    | svn
131 netradiant                    |                                                   | master         |
132 div0-gittools                 |                                                   | master         | no
133 d0_blind_id                   |                                                   | master         |
134 data/xonotic-maps.pk3dir      |                                                   | master         |
135 mediasource                   |                                                   | master         | no
136 fteqcc                        |                                                   | xonotic-stable | noautocrlf
137 "
138 # todo: in darkplaces, change repobranch to div0-stable
139
140 repos=`$ECHO "$repos_urls" | grep . | cut -d '|' -f 1 | tr -d ' '`
141
142 base=`git config remote.origin.url`
143 case "$base" in
144         */xonotic.git)
145                 base=${base%xonotic.git}
146                 ;;
147         *)
148                 $ECHO "The main repo is not xonotic.git, what have you done?"
149                 exit 1
150                 ;;
151 esac
152 pushbase=`git config remote.origin.pushurl || true`
153 case "$pushbase" in
154         */xonotic.git)
155                 pushbase=${pushbase%xonotic.git}
156                 ;;
157         '')
158                 ;;
159         *)
160                 $ECHO "The main repo is not xonotic.git, what have you done?"
161                 exit 1
162                 ;;
163 esac
164
165 repourl()
166 {
167         repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
168         if [ -n "$repo_t" ]; then
169                 case "$repo_t" in
170                         *://*)
171                                 $ECHO "$repo_t"
172                                 ;;
173                         *)
174                                 $ECHO "$base$repo_t"
175                                 ;;
176                 esac
177         else
178                 if [ x"$1" = x"." ]; then
179                         $ECHO "$base""xonotic.git"
180                 else
181                         $ECHO "$base${1##*/}.git"
182                 fi
183         fi
184 }
185
186 repopushurl()
187 {
188         [ -n "$pushbase" ] || return 0
189         repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 2 | tr -d ' '`
190         if [ -n "$repo_t" ]; then
191                 case "$repo_t" in
192                         *://*)
193                                 ;;
194                         *)
195                                 $ECHO "$pushbase$repo_t"
196                                 ;;
197                 esac
198         else
199                 if [ x"$1" = x"." ]; then
200                         $ECHO "$pushbase""xonotic.git"
201                 else
202                         $ECHO "$pushbase${1##*/}.git"
203                 fi
204         fi
205 }
206
207 repobranch()
208 {
209         repo_t=`$ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 3 | tr -d ' '`
210         if [ -n "$repo_t" ]; then
211                 $ECHO "$repo_t"
212         else
213                 $ECHO "master"
214         fi
215 }
216
217 repoflags()
218 {
219         $ECHO "$repos_urls" | grep "^$1 " | cut -d '|' -f 4 | tr -d ' '
220 }
221
222 listrepos()
223 {
224         for d in $repos; do
225                 p="${d%dir}"
226                 f="`repoflags "$d"`"
227                 # if we have .no file, skip
228                 if [ -f "$d.no" ]; then
229                         msg "Repository $d disabled by a .no file, delete $d.no to enable"
230                         continue
231                 fi
232                 # if .yes file exists, always keep it
233                 if [ -f "$d.yes" ]; then
234                         msg "Repository $d enabled by a .yes file"
235                         $ECHO "$d"
236                         continue
237                 fi
238                 # remove broken clones so they don't mess up stuff
239                 if [ x"$d" != x"." ] && [ -d "$d" ] && ! [ -d "$d/.git" ]; then
240                         msg "$d exists but has no .git subdir. Probably a broken clone. Deleting."
241                         verbose rm -rf "$d"
242                         continue
243                 fi
244                 # if we have the dir, always keep it
245                 if [ -d "$d" ]; then
246                         msg "Repository $d enabled because it already exists"
247                         $ECHO "$d"
248                         continue
249                 fi
250                 # if we have matching pk3, skip
251                 if [ x"$p" != x"$d" ] && [ -f "$p" ]; then
252                         msg "Repository $d disabled by matching .pk3 file, delete $p or create $d.yes to enable"
253                         continue
254                 fi
255                 # if "no" flag is set, skip
256                 case ",$f," in
257                         *,no,*)
258                                 msg "Repository $d disabled by default, create $d.yes to enable"
259                                 continue
260                                 ;;
261                 esac
262                 # default: enable
263                 msg "Repository $d enabled by default"
264                 $ECHO "$d"
265         done
266 }
267
268 repos=`listrepos`
269
270 if [ "$#" = 0 ]; then
271         set -- help
272 fi
273 cmd=$1
274 shift
275
276 case "$cmd" in
277         release|release-*)
278                 export LC_ALL=C
279
280                 release_args="$cmd $*"
281                 msg "*** $release_args: start"
282                 release_starttime=`date +%s`
283                 release_end()
284                 {
285                         release_endtime=`date +%s`
286                         release_deltatime=$(($release_endtime - $release_starttime))
287                         msg "*** $release_args: $release_deltatime seconds"
288                 }
289                 trap release_end EXIT
290                 release_tempstarttime=$release_starttime
291                 release_timereport()
292                 {
293                         release_endtime=`date +%s` # RELEASE NOW!!!
294                         if [ -n "$*" ]; then
295                                 release_deltatime=$(($release_endtime - $release_tempstarttime))
296                                 msg "**** $release_args: $*: $release_deltatime seconds"
297                         fi
298                         release_tempstarttime=$release_endtime
299                 }
300                 release_git_extract_dir()
301                 {
302                         release_src=$1; shift
303                         release_dst=$1; shift
304                         # try to create a hardlink
305                         if ln -f "$release_src/.git/HEAD" "$release_dst/.hardlink-test"; then
306                                 rm -f "$release_dst/.hardlink-test"
307                                 {
308                                         verbose cd "$release_src"
309                                         git ls-files HEAD -- "$@"
310                                 } | {
311                                         while IFS= read -r F; do
312                                                 case "$F" in */*) mkdir -p "$release_dst/${F%/*}" ;; esac
313                                                 verbose ln -f "$release_src/$F" "$release_dst/$F"
314                                         done
315                                 }
316                         else
317                                 {
318                                         verbose cd "$release_src"
319                                         verbose git archive --format=tar HEAD -- "$@"
320                                 } | {
321                                         verbose cd "$release_dst"
322                                         verbose tar xvf -
323                                 }
324                         fi
325                 }
326                 ;;
327 esac
328
329 fix_upstream_rebase()
330 {
331         if [ -z "$r_me" ] || [ -z "$r_other" ]; then
332                 return
333         fi
334
335         # one of the two sides of the merge should be remote upstream, or all is fine
336         r_r=`git symbolic-ref HEAD`
337         r_r=${r_r#refs/heads/}
338         r_rem=`git config "branch.$r_rem.remote" || $ECHO origin`
339         r_bra=`git config "branch.$r_bra.merge" || $ECHO "$r_r"`
340         r_bra=${r_bra#refs/heads/}
341         if [ x"$r_me" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
342                 if [ x"$r_other" != x"`git rev-parse "$r_rem/$r_bra"`" ]; then
343                         return
344                 fi
345         fi
346
347         r_base=`git merge-base "$r_me" "$r_other"`
348
349         # no merge-base? upstream did filter-branch
350         if [ -n "$r_base" ]; then
351                 # otherwise, check if the two histories are "similar"
352                 r_l_me=`git log --pretty="format:%s" "$r_other".."$r_me" | grep -v "^Merge" | sort -u`
353                 r_l_other=`git log --pretty="format:%s" "$r_me".."$r_other" | grep -v "^Merge" | sort -u`
354
355                 # heuristics: upstream rebase/filter-branch if more than 50% of the commits of one of the sides are in the other too
356                 r_lc_me=`$ECHO "$r_l_me" | wc -l`
357                 r_lc_other=`$ECHO "$r_l_other" | wc -l`
358                 r_lc_together=`{ $ECHO "$r_l_me"; $ECHO "$r_l_other"; } | sort -u | wc -l`
359                 r_lc_same=$(($r_lc_me + $r_lc_other - $r_lc_together))
360
361                 if [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_me )) ] || [ $(( $r_lc_same * 2 )) -gt $(( $r_lc_other )) ]; then
362                         if yesno "Probable upstream rebase detected, automatically fix?" 'git log --oneline --graph --date-order --left-right "$r_other"..."$r_me"'; then
363                                 git reset --hard "$r_me"
364                                 git pull --rebase
365                                 return 1
366                         fi
367                 fi
368         fi
369
370         return 0
371 }
372
373 fix_upstream_rebase_mergeok()
374 {
375         r_me=`git rev-parse --revs-only HEAD^1 2>/dev/null || true`
376         r_other=`git rev-parse --revs-only HEAD^2 2>/dev/null || true`
377         fix_upstream_rebase
378 }
379
380 fix_upstream_rebase_mergefail()
381 {
382         r_me=`git rev-parse --revs-only HEAD 2>/dev/null || true`
383         r_other=`git rev-parse --revs-only MERGE_HEAD 2>/dev/null || true`
384         fix_upstream_rebase
385 }
386
387 fix_git_config()
388 {
389         if ! [ -f ".git/config" ]; then
390                 $ECHO "Not a git repository. Bailing out to not cause damage."
391                 exit 1
392         fi
393         verbose git config remote.origin.url "$1"
394         if [ -n "$2" ]; then
395                 verbose git config remote.origin.pushurl "$2"
396         else
397                 verbose git config --unset remote.origin.pushurl || true
398         fi
399         verbose git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
400         case ",`repoflags "$d"`," in
401                 *,noautocrlf,*)
402                         verbose git config --unset core.autocrlf || true
403                         ;;
404                 *)
405                         verbose git config core.autocrlf input
406                         ;;
407         esac
408         if [ -z "`git config push.default || true`" ]; then
409                 verbose git config push.default current # or is tracking better?
410         fi
411         verbose git config filter.mapclean.clean "tr -d '\r' | grep '^[^/]'"
412         verbose git config filter.mapclean.smudge "cat"
413 }
414
415 mkzipr()
416 {
417         archive=$1; shift
418         case "$RELEASETYPE" in
419                 release)
420                         sevenzipflags=-mx=9
421                         zipflags=-9
422                         ;;
423                 *)
424                         sevenzipflags=-mx=1
425                         zipflags=-1
426                         ;;
427         esac
428         find "$@" -exec touch -d "2001-01-01 01:01:01 +0000" {} \+ # ugly hack to make the pk3 files rsync-friendly
429         ziplist=`mktemp`
430         find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
431         7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
432         zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
433         rm -f "$ziplist"
434 }
435
436 mkzip()
437 {
438         archive=$1; shift
439         case "$RELEASETYPE" in
440                 release)
441                         sevenzipflags=-mx=9
442                         zipflags=-9
443                         ;;
444                 *)
445                         sevenzipflags=-mx=1
446                         zipflags=-1
447                         ;;
448         esac
449         ziplist=`mktemp`
450         find "$@" -xtype f \( -executable -or -type l \) -print > "$ziplist"
451         7za a -tzip $sevenzipflags -x@"$ziplist" "$archive" "$@" || true
452         zip         $zipflags -y   -@<"$ziplist" "$archive"      || true
453         rm -f "$ziplist"
454 }
455
456 mkzip0()
457 {
458         archive=$1; shift
459         zip -0ry "$archive" "$@"
460 }
461
462 mirrorspeed()
463 {
464         # first result is to be ignored, but we use it to check status
465         git ls-remote "$1" refs/heads/master >/dev/null 2>&1 || return 1
466         { 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*,,'
467                 # unit: clock ticks (depends on what "time" returns
468 }
469
470 bestmirror()
471 {
472         pre=$1; shift
473         suf=$1; shift
474
475         if ! { time -p true; } >/dev/null 2>&1; then
476                 msg "Cannot do timing in this shell"
477                 return 1
478         fi
479
480         bestin=
481         bestt=
482         for mir in "$@"; do
483                 case "$mir" in
484                         *:*)
485                                 in=${mir%%:*}
486                                 op=${mir#*:}
487                                 ;;
488                         *)
489                                 in=$mir
490                                 op=
491                                 ;;
492                 esac
493                 m=$pre$in$suf
494                 if t=`mirrorspeed "$m"`; then
495                         if [ -n "$t" ]; then
496                                 tt=$(($t$op)) # fudge factor
497                                 msg "$m -> $t$op = $tt ticks"
498                                 if [ -z "$bestt" ] || [ "$tt" -lt "$bestt" ]; then
499                                         bestin=$in
500                                         bestt=$tt
501                                 fi
502                         else
503                                 msg "$m -> error"
504                         fi
505                 else
506                         msg "$m -> FAIL"
507                 fi
508         done
509         if [ -n "$bestin" ]; then
510                 msg "Best mirror seems to be $pre$bestin$suf"
511                 $ECHO "$bestin"
512         else
513                 return 1
514         fi
515 }
516
517 case "$cmd" in
518         fix_upstream_rebase)
519                 for d in $repos; do
520                         enter "$d0/$d" verbose
521                         verbose fix_upstream_rebase_mergefail && verbose fix_upstream_rebase_mergeok
522                 done
523                 ;;
524         fix_config)
525                 for d in $repos; do
526                         url=`repourl "$d"`
527                         pushurl=`repopushurl "$d"`
528                         branch=`repobranch "$d"`
529                         if [ -f "$d0/$d/.git/config" ]; then
530                                 verbose cd "$d0/$d"
531                                 fix_git_config "$url" "$pushurl"
532                                 cd "$d0"
533                         fi
534                 done
535                 ;;
536         keygen)
537                 # enable the ssh URL for pushing
538                 "$SELF" update -N -p
539
540                 if [ -f ~/.ssh/id_rsa.pub ]; then
541                         msg ""
542                         msg "A key already exists and no new one will be generated. If you"
543                         msg "already have done the procedure for getting your key approved, you"
544                         msg "can skip the following paragraph and already use the repository."
545                         msg ""
546                         msg "To get access, your key has to be approved first. For that, visit"
547                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
548                         msg "the \"Support\" tracker in the \"Repository\" category where you"
549                         msg "apply for access and paste the following output into the issue:"
550                         msg ""
551                         msg "`cat ~/.ssh/id_rsa.pub`"
552                         msg ""
553                         msg "Note that you will only have write access to branches that start"
554                         msg "with your user name."
555                 elif [ -f ~/.ssh/id_dsa.pub ]; then
556                         msg ""
557                         msg "A key already exists and no new one will be generated. If you"
558                         msg "already have done the procedure for getting your key approved, you"
559                         msg "can skip the following paragraph and already use the repository."
560                         msg ""
561                         msg "To get access, your key has to be approved first. For that, visit"
562                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
563                         msg "the \"Support\" tracker in the \"Repository\" category where you"
564                         msg "apply for access and paste the following output into the issue:"
565                         msg ""
566                         msg "`cat ~/.ssh/id_dsa.pub`"
567                         msg ""
568                         msg "Note that you will only have write access to branches that start"
569                         msg "with your user name."
570                 else
571                         msg ""
572                         msg "No key has been generated yet. One will be generated now."
573                         msg "If other people are using your computer, it is recommended"
574                         msg "to specify a passphrase. Otherwise you can simply hit ENTER"
575                         msg "when asked for a passphrase."
576                         msg ""
577                         ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
578                         msg ""
579                         msg "To get access, your key has to be approved first. For that, visit"
580                         msg "http://dev.xonotic.org/, then log in, create a \"New Issue\" on"
581                         msg "the \"Support\" tracker in the \"Repository\" category where you"
582                         msg "apply for access and paste the following output into the issue:"
583                         msg ""
584                         msg "`cat ~/.ssh/id_rsa.pub`"
585                         msg ""
586                         msg "Note that you will only have write access to branches that start"
587                         msg "with your user name."
588                 fi
589                 ;;
590         update|pull)
591                 allow_pull=true
592                 location=current
593                 oldbase=$base
594                 oldpushbase=$pushbase
595                 # transition old URLs
596                 if [ x"$base" = x"ssh://xonotic@push.git.xonotic.org/" ]; then
597                         base=ssh://xonotic@push.git.xonotic.org/
598                 fi
599                 while :; do
600                         if [ x"$1" = x"-N" ]; then
601                                 allow_pull=false
602                         elif [ x"$1" = x"-p" ]; then
603                                 pushbase=ssh://xonotic@push.git.xonotic.org/
604                         elif [ x"$1" = x"-ps" ]; then
605                                 pushbase=ssh://xonotic@push.git.xonotic.org/
606                         elif [ x"$1" = x"-ph" ]; then
607                                 pushbase=http://push.git.xonotic.org/login/xonotic/
608                         elif [ x"$1" = x"-s" ]; then
609                                 base=ssh://xonotic@push.git.xonotic.org/
610                         elif [ x"$1" = x"-g" ]; then
611                                 base=git://git.xonotic.org/xonotic/
612                                 location=best
613                         elif [ x"$1" = x"-h" ]; then
614                                 base=http://git.xonotic.org/xonotic/
615                                 location=best
616                         elif [ x"$1" = x"-l" ]; then
617                                 case "$2" in
618                                         nl) ;;
619                                         de) ;;
620                                         us) ;;
621                                         best) ;;
622                                         default) ;;
623                                         *)
624                                                 msg "Invalid location!"
625                                                 msg "Possible locations for the -l option:"
626                                                 msg "  nl (Netherlands, run by merlijn)"
627                                                 msg "  de (Germany, run by divVerent)"
628                                                 msg "  us (United States of America, run by detrate)"
629                                                 msg "  best (find automatically)"
630                                                 msg "  default (currently nl)"
631                                                 exit 1
632                                                 ;;
633                                 esac
634                                 location=$2
635                                 shift
636                         else
637                                 break
638                         fi
639                         shift
640                 done
641                 case "$location" in
642                         current)
643                                 if [ x"`git config xonotic.all.mirrorselection 2>/dev/null || true`" != x"done" ]; then
644                                         location=best
645                                 fi
646                                 ;;
647                 esac
648                 case "$location" in
649                         best)
650                                 # if we fetched via ssh://, switch to git:// for fetching and keep using ssh:// for pushing
651                                 case "$base" in
652                                         ssh://*|*/login/*)
653                                                 pushbase=$base
654                                                 base=git://git.xonotic.org/xonotic/
655                                                 ;;
656                                 esac
657                                 newbase=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,:// .git.xonotic.org/,"`
658                                 case "$newbase" in
659                                         *\ *)
660                                                 if location=`bestmirror $newbase"xonotic.git" de us nl:'*6/5'`; then # 20% malus to the NL server to not overload it too much
661                                                         git config xonotic.all.mirrorselection done
662                                                 else
663                                                         location=current
664                                                 fi
665                                                 ;;
666                                         *)
667                                                 location=current
668                                                 ;;
669                                 esac
670                                 ;;
671                 esac
672                 case "$location" in
673                         default)
674                                 location=
675                                 ;;
676                         current)
677                                 case "$base" in
678                                         *://*.git.xonotic.org/*)
679                                                 location=${base%%.git.xonotic.org/*}
680                                                 location=${location##*://}
681                                                 ;;
682                                         *)
683                                                 location=
684                                                 ;;
685                                 esac
686                                 ;;
687                 esac
688                 if [ -n "$location" ]; then
689                         base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://$location.git.xonotic.org/,"`
690                 else
691                         base=`$ECHO "$base" | sed "s,://\(.*\.\)\?git.xonotic.org/,://git.xonotic.org/,"`
692                 fi
693                 pushbase=`$ECHO "$pushbase" | sed "s,://\(.*\.\)\?git.xonotic.org/,://xonotic@push.git.xonotic.org/,"`
694                 if [ x"$base" != x"$oldbase" ] || [ x"$pushbase" != x"$oldpushbase" ]; then
695                         url=`repourl .`
696                         pushurl=`repopushurl .`
697                         fix_git_config "$url" "$pushurl"
698                         "$SELF" fix_config
699                 elif $allow_pull; then
700                         "$SELF" fix_config
701                 fi
702                 for d in $repos; do
703                         url=`repourl "$d"`
704                         pushurl=`repopushurl "$d"`
705                         branch=`repobranch "$d"`
706                         if [ -f "$d0/$d/.git/config" ]; then
707                                 # if we have .no file, skip
708                                 if [ -f "$d0/$d.no" ]; then
709                                         msg "Repository $d disabled by a .no file, delete $d.no to enable; thus, not updated"
710                                         continue
711                                 fi
712                                 if $allow_pull; then
713                                         enter "$d0/$d" verbose
714                                         r=`git symbolic-ref HEAD`
715                                         r=${r#refs/heads/}
716                                         if git config branch.$r.remote >/dev/null 2>&1; then
717                                                 if ! verbose git pull; then
718                                                         fix_upstream_rebase_mergefail || true
719                                                         check_mergeconflict "$d"
720                                                         $ECHO "Pulling failed. Press ENTER to continue, or Ctrl-C to abort."
721                                                         read -r DUMMY
722                                                 else
723                                                         fix_upstream_rebase_mergeok || true
724                                                 fi
725                                         fi
726
727                                         cd "$d00"
728                                         checkself "$cmd" "$@"
729                                         cd "$d0/$d"
730                                         verbose git remote prune origin
731                                         cd "$d0"
732                                 fi
733                         else
734                                 if [ -d "$d0/$d" ]; then
735                                         if yesno "$d0/$d is in the way, get rid of it and reclone?"; then
736                                                 verbose rm -rf "$d0/$d"
737                                         else
738                                                 echo "Note: $d0/$d will stay broken."
739                                                 continue
740                                         fi
741                                 fi
742                                 verbose git clone "$url" "$d0/$d"
743                                 enter "$d0/$d" verbose
744                                 fix_git_config "$url" "$pushurl"
745                                 if [ "$branch" != "master" ]; then
746                                         verbose git checkout --track -b "$branch" origin/"$branch"
747                                 fi
748                                 cd "$d0"
749                         fi
750                 done
751                 ;;
752         update-maps)
753                 misc/tools/xonotic-map-compiler-autobuild download
754                 ;;
755         checkout|switch)
756                 checkoutflags=
757                 if [ x"$1" = x"-f" ]; then
758                         checkoutflags=-f
759                         shift
760                 fi
761                 remote=$1
762                 branch=$2
763                 if [ -z "$branch" ]; then
764                         case "$remote" in
765                                 origin/*)
766                                         branch=${remote#origin/}
767                                         remote=origin
768                                         ;;
769                                 *)
770                                         branch=$remote
771                                         remote=origin
772                                         ;;
773                         esac
774                 fi
775                 if [ -n "$checkoutflags" ]; then
776                         set -- -f "$@" # to make checkself work again
777                 fi
778                 exists=false
779                 for d in $repos; do
780                         enter "$d0/$d" verbose
781                         b=$branch
782                         if [ -n "$b" ] && git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
783                                 exists=true
784                                 verbose git checkout $checkoutflags "$b"
785                         elif [ -n "$b" ] && git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
786                                 exists=true
787                                 verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
788                         else
789                                 b=`repobranch "$d"`
790                                 if git rev-parse "refs/heads/$b" >/dev/null 2>&1; then
791                                         verbose git checkout $checkoutflags "$b"
792                                 elif git rev-parse "refs/remotes/$remote/$b" >/dev/null 2>&1; then
793                                         verbose git checkout $checkoutflags --track -b "$b" "$remote/$b"
794                                 else
795                                         $ECHO "WTF? Not even branch $b doesn't exist in $d"
796                                         exit 1
797                                 fi
798                         fi
799                         cd "$d00"
800                         checkself "$cmd" "$@"
801                         cd "$d0"
802                 done
803                 if ! $exists; then
804                         $ECHO "The requested branch was not found in any repository."
805                 fi
806                 exec "$SELF" branch
807                 ;;
808         branch)
809                 remote=$1
810                 branch=$2
811                 srcbranch=$3
812                 if [ -z "$branch" ]; then
813                         branch=$remote
814                         remote=origin
815                 fi
816                 if [ -z "$branch" ]; then
817                         for d in $repos; do
818                                 enter "$d0/$d"
819                                 r=`git symbolic-ref HEAD`
820                                 r=${r#refs/heads/}
821                                 $ECHO "$d is at $r"
822                                 cd "$d0"
823                         done
824                 else
825                         for d in $repos; do
826                                 dv=`visible_repo_name "$d"`
827                                 enter "$d0/$d" verbose
828                                 if git rev-parse "refs/heads/$branch" >/dev/null 2>&1; then
829                                         $ECHO "Already having this branch in $dv."
830                                 else
831                                         if yesno "Branch in $dv?"; then
832                                                 if [ -n "$srcbranch" ]; then
833                                                         b=$srcbranch
834                                                 else
835                                                         b=origin/"`repobranch "$d"`"
836                                                         verbose git fetch origin || true
837                                                 fi
838                                                 # TODO do this without pushing
839                                                 verbose git checkout -b "$branch" "$b"
840                                                 verbose git config "branch.$branch.remote" "$remote"
841                                                 verbose git config "branch.$branch.merge" "refs/heads/$branch"
842                                         fi
843                                 fi
844                                 cd "$d0"
845                         done
846                         "$SELF" branch
847                 fi
848                 ;;
849         branches)
850                 for d in $repos; do
851                         cd "$d0/$d" # am in a pipe, shouldn't use enter
852                         git branch -r -v -v | cut -c 3- | sed "s/^(no branch)/(no_branch)/" | sed "s,^,$d ,"
853                         cd "$d0"
854                 done | {
855                         branches_list=
856                         # branches_repos_*=
857                         while read -r d BRANCH REV TEXT; do
858                                 if [ x"$BRANCH" = x"`repobranch "$d"`" ]; then
859                                         continue
860                                 fi
861                                 if [ x"$REV" = x"->" ]; then
862                                         continue
863                                 fi
864                                 BRANCH=${BRANCH#remotes/}
865                                 ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
866                                 branches_list="$branches_list $BRANCH" # TEH SORT MAKEZ IT UNIEQ
867                                 eval "r=\$branches_repos_$ID"
868                                 r="$r $d"
869                                 eval "branches_repos_$ID=\$r"
870                         done
871                         $ECHO -n "$branches_list" | xargs -n 1 $ECHO | sort -u | while IFS= read -r BRANCH; do
872                                 ID=`$ECHO "$BRANCH" | tr -c "A-Za-z0-9." "_"`
873                                 eval "r=\$branches_repos_$ID"
874                                 printf "%-60s %s\n" "$BRANCH" "$r"
875                                 #$ECHO "$BRANCH: $r"
876                         done
877                 }
878                 ;;
879         merge)
880                 for d in $repos; do
881                         dv=`visible_repo_name "$d"`
882                         enter "$d0/$d" verbose
883                         r=`git symbolic-ref HEAD`
884                         r=${r#refs/heads/}
885                         if git log HEAD..origin/"`repobranch "$d"`" | grep .; then
886                                 # we have uncommitted changes
887                                 if yesno "Could merge from \"`repobranch "$d"`\" into \"$r\" in $dv. Do it?"; then
888                                         if ! verbose git merge origin/"`repobranch "$d"`"; then
889                                                 check_mergeconflict "$d"
890                                                 exit 1 # this should ALWAYS be fatal
891                                         fi
892                                 fi
893                         fi
894                         cd "$d0"
895                 done
896                 ;;
897         push|commit)
898                 submit=$1
899                 for d in $repos; do
900                         dv=`visible_repo_name "$d"`
901                         enter "$d0/$d" verbose
902                         r=`git symbolic-ref HEAD`
903                         r=${r#refs/heads/}
904                         diffdata=`git diff --color HEAD`
905                         if [ -n "$diffdata" ]; then
906                                 # we have uncommitted changes
907                                 if yesno "Uncommitted changes in \"$r\" in $dv. Commit?" '$ECHO "$diffdata" | less -r'; then
908                                         verbose git commit -a
909                                 fi
910                         fi
911                         rem=`git config "branch.$r.remote" || $ECHO origin`
912                         bra=`git config "branch.$r.merge" || $ECHO "$r"`
913                         upstream="$rem/${bra#refs/heads/}"
914                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
915                                 upstream="origin/`repobranch "$d"`"
916                         fi
917                         logdata=`git log --color "$upstream".."$r"`
918                         if [ -n "$logdata" ]; then
919                                 if yesno "Push \"$r\" in $dv?" '$ECHO "$logdata" | less -r'; then
920                                         verbose git push "$rem" HEAD
921                                 fi
922                         fi
923                         if [ x"$submit" = x"-s" ]; then
924                                 case "$r" in
925                                         */*)
926                                                 verbose git push "$rem" HEAD:"${bra%%/*}/finished/${bra#*/}"
927                                                 ;;
928                                 esac
929                         fi
930                         cd "$d0"
931                 done
932                 ;;
933         compile)
934                 cleand0=false
935                 cleandp=false
936                 cleanqcc=false
937                 cleanqc=false
938                 compiled0=false
939                 debug=debug
940                 snowleopardhack=false
941                 if [ -z "$CC" ]; then
942                         export CC="gcc -DSUPPORTIPV6"
943                 fi
944                 while :; do
945                         case "$1" in
946                                 -0)
947                                         compiled0=true
948                                         shift
949                                         ;;
950                                 -c)
951                                         cleand0=true
952                                         cleandp=true
953                                         cleanqcc=true
954                                         cleanqc=true
955                                         shift
956                                         ;;
957                                 -r|-p)
958                                         case "$1" in
959                                                 -p)
960                                                         debug=profile
961                                                         ;;
962                                                 -r)
963                                                         debug=release
964                                                         ;;
965                                         esac
966                                         export CC="$CC -g"
967                                         case "`$CC -dumpversion`" in
968                                                 [5-9]*|[1-9][0-9]*|4.[3-9]*|4.[1-9][0-9]*)
969                                                         # gcc 4.3 or higher
970                                                         # -march=native is broken < 4.3
971                                                         if $CC -mtune=native -march=native misc/tools/conftest.c -o conftest >/dev/null 2>&1; then
972                                                                 export CC="$CC -mtune=native -march=native"
973                                                         fi
974                                                         ;;
975                                         esac
976                                         if [ -n "$WE_HATE_OUR_USERS" ]; then
977                                                 export CC="$CC -fno-common"
978                                         fi
979                                         shift
980                                         ;;
981                                 *)
982                                         break
983                                         ;;
984                         esac
985                 done
986                 if [ -n "$WE_HATE_OUR_USERS" ]; then
987                         TARGETS="sv-$debug cl-$debug"
988                 elif [ x"`uname`" = x"Darwin" ]; then
989                         case "`uname -r`" in
990                                 ?.*)
991                                         TARGETS="sv-$debug cl-$debug sdl-$debug"
992                                         ;;
993                                 *)
994                                         # AGL cannot be compiled on systems with a kernel > 10.x (Snow Leopard)
995                                         snowleopardhack=true
996                                         TARGETS="sv-$debug sdl-$debug"
997                                         ;;
998                         esac
999                         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"
1000                 else
1001                         TARGETS="sv-$debug cl-$debug sdl-$debug"
1002                 fi
1003                 if [ $# -gt 0 ] && [ x"$1" = x"" ]; then
1004                         # if we give the command make the arg "", it will surely fail (invalid filename),
1005                         # so better handle it as an empty client option
1006                         BAD_TARGETS=" "
1007                         shift
1008                 elif [ -n "$1" ]; then
1009                         BAD_TARGETS=
1010                         TARGETS_SAVE=$TARGETS
1011                         TARGETS=
1012                         for X in $1; do
1013                                 case "$X" in
1014                                         sdl)
1015                                                 TARGETS="$TARGETS sdl-debug"
1016                                                 ;;
1017                                         agl)
1018                                                 TARGETS="$TARGETS cl-debug"
1019                                                 if $snowleopardhack; then
1020                                                         export CC="$CC -arch i386"
1021                                                 fi
1022                                                 ;;
1023                                         glx|wgl)
1024                                                 TARGETS="$TARGETS cl-debug"
1025                                                 ;;
1026                                         dedicated)
1027                                                 TARGETS="$TARGETS sv-debug"
1028                                                 ;;
1029                                         *)
1030                                                 BAD_TARGETS="$BAD_TARGETS $X"
1031                                                 ;;
1032                                 esac
1033                         done
1034                         if [ -n "$TARGETS" ]; then # at least a valid client
1035                                 shift
1036                         else # no valid client, let's assume this option is not meant to be a client then
1037                                 TARGETS=$TARGETS_SAVE
1038                                 BAD_TARGETS=
1039                         fi
1040                 fi
1041                 if [ -z "$MAKEFLAGS" ]; then
1042                         if [ -f /proc/cpuinfo ]; then
1043                                 ncpus=$((`grep -c '^processor   :' /proc/cpuinfo || true`+0))
1044                                 if [ $ncpus -gt 1 ]; then
1045                                         MAKEFLAGS=-j$ncpus
1046                                 fi
1047                         fi
1048                         if [ -n "$WE_HATE_OUR_USERS" ]; then
1049                                 MAKEFLAGS="$MAKEFLAGS DP_MAKE_TARGET=mingw LIB_JPEG= CFLAGS_LIBJPEG="
1050                         fi
1051                 fi
1052
1053                 
1054                 if ! verbose $CC misc/tools/conftest.c -o conftest; then
1055                         msg ""
1056                         msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
1057                         msg "~~~~~~~~~~ COMPILER ~~~~~~~~~~"
1058                         msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
1059                         msg "~~~~~~~~~~~~~~_...._~~~~~~~~~~"
1060                         msg "~~~~~~~~~~~,-'     \\\`-._~~~~~~"
1061                         msg "~~~~~~~~~~/     --. ><  \\~~~~~"
1062                         msg "~~~~~~~~~/      (*)> -<: \\~~~~"
1063                         msg "~~~~~~~~~(     ^~-'  (*) )~~~~"
1064                         msg "~~~~~~~~~\\        ^+-_/  |~~~~"
1065                         msg "~~~~~~~~~~\\       {vvv}  |~~~~"
1066                         msg "~~~~~~~~~~,\\    , {^^^},/~~~~~"
1067                         msg "~~~~~~~~,/  \`---.....-'~~W~~~~"
1068                         msg "~~~~~~,/   \\_____/_\\_W~~/~~~~~"
1069                         msg "~~~~~/          /~~~\\__/~~~~~~"
1070                         msg "~~~~/          /~~~~~~~~~~~~~~"
1071                         msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
1072                         msg "~~~~~~~ Y U NO COMPILE ~~~~~~~"
1073                         msg "~~~~~~~~~~~~ CODE ~~~~~~~~~~~~"
1074                         msg "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
1075                         msg ""
1076                         exit 1
1077                 fi
1078                 rm -f conftest
1079
1080                 verbose cd "$d0/d0_blind_id"
1081                 if ! $compiled0; then
1082                         # compilation of crypto library failed
1083                         # use binaries then, if we can...
1084                         mkdir -p .libs
1085                         if [ -n "$WE_HATE_OUR_USERS" ]; then
1086                                 verbose cp "$d0/misc/buildfiles/win32/libd0_blind_id"-* .libs/
1087                                 verbose cp "$d0/misc/buildfiles/win32/libd0_rijndael"-* .libs/
1088                                 verbose cp "$d0/misc/buildfiles/win32/libgmp"-* .libs/
1089                         else
1090                                 case "`uname`" in
1091                                         Linux)
1092                                                 case `uname -m` in
1093                                                         x86_64)
1094                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_blind_id".* .libs/
1095                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libd0_rijndael".* .libs/
1096                                                                 #verbose cp "$d0/misc/builddeps/dp.linux64/lib/libgmp".* .libs/
1097                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux64/lib/"
1098                                                                 ;;
1099                                                         *86)
1100                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_blind_id".* .libs/
1101                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libd0_rijndael".* .libs/
1102                                                                 #verbose cp "$d0/misc/builddeps/dp.linux32/lib/libgmp".* .libs/
1103                                                                 MAKEFLAGS="$MAKEFLAGS DP_CRYPTO_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/ DP_CRYPTO_RIJNDAEL_STATIC_LIBDIR=../misc/builddeps/dp.linux32/lib/"
1104                                                                 ;;
1105                                                         *)
1106                                                                 compiled0=true
1107                                                                 ;;
1108                                                 esac
1109                                                 ;;
1110                                         Darwin)
1111                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_blind_id".* .libs/
1112                                                 verbose cp "$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS/libd0_rijndael".* .libs/
1113                                                 ;;
1114                                         *)
1115                                                 compiled0=true
1116                                                 ;;
1117                                 esac
1118                         fi
1119                 fi
1120                 if $compiled0; then
1121                         if $cleand0; then
1122                                 if [ -f Makefile ]; then
1123                                         verbose make $MAKEFLAGS distclean
1124                                 fi
1125                         fi
1126                         if ! [ -f Makefile ]; then
1127                                 verbose sh autogen.sh
1128                                 verbose ./configure
1129                         fi
1130                         verbose make $MAKEFLAGS
1131                 fi
1132
1133                 verbose cd "$d0/fteqcc"
1134                 if $cleanqcc; then
1135                         verbose make $MAKEFLAGS clean
1136                 fi
1137                 verbose make $MAKEFLAGS
1138
1139                 verbose cd "$d0/data/xonotic-data.pk3dir"
1140                 if $cleanqc; then
1141                         verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS clean
1142                 fi
1143                 verbose make FTEQCC="../../../../fteqcc/fteqcc.bin" "$@" $MAKEFLAGS
1144                 # 4 levels up: data, xonotic-data, qcsrc, server
1145
1146                 verbose cd "$d0/darkplaces"
1147                 if [ x"$BAD_TARGETS" = x" " ]; then
1148                         $ECHO "Warning: invalid empty client, default clients will be used."
1149                 fi
1150                 if $cleandp; then
1151                         verbose make $MAKEFLAGS clean
1152                 fi
1153                 for T in $TARGETS; do
1154                         verbose make $MAKEFLAGS STRIP=: "$@" "$T"
1155                 done
1156                 for T in $BAD_TARGETS; do
1157                         $ECHO "Warning: discarded invalid client $T."
1158                 done
1159
1160                 verbose "$SELF" update-maps
1161                 ;;
1162         run)
1163                 if [ -n "$WE_HATE_OUR_USERS" ]; then
1164                         client=
1165                         export PATH="$d0/misc/buildfiles/win32:$d0/d0_blind_id/.libs:$PATH"
1166                 elif [ x"`uname`" = x"Darwin" ]; then
1167                         export DYLD_LIBRARY_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/MacOS:$d0/d0_blind_id/.libs"
1168                         export DYLD_FRAMEWORK_PATH="$d0/misc/buildfiles/osx/Xonotic.app/Contents/Frameworks"
1169                         client=-sdl
1170                 else
1171                         export LD_LIBRARY_PATH="$d0/d0_blind_id/.libs"
1172                         client=-sdl
1173                 fi
1174                 case "$1" in
1175                         sdl|glx|agl|dedicated)
1176                                 client=-$1
1177                                 shift
1178                                 ;;
1179                         wgl)
1180                                 client=
1181                                 shift
1182                                 ;;
1183                 esac
1184                 if ! [ -x "darkplaces/darkplaces$client" ]; then
1185                         if [ -x "darkplaces/darkplaces$client.exe" ]; then
1186                                 client=$client.exe
1187                         else
1188                                 $ECHO "Client darkplaces/darkplaces$client not found, aborting"
1189                                 exit 1
1190                         fi
1191                 fi
1192                 set -- "darkplaces/darkplaces$client" -xonotic "$@"
1193
1194                 # if pulseaudio is running: USE IT
1195                 if [ -z "$SDL_AUDIODRIVER" ] && ! [ -n "$WE_HATE_OUR_USERS" ] && ! [ x"`uname`" = x"Darwin" ]; then
1196                         if ps -C pulseaudio >/dev/null; then
1197                                 if ldd /usr/lib/libSDL.so 2>/dev/null | grep pulse >/dev/null; then
1198                                         export SDL_AUDIODRIVER=pulse
1199                                 fi
1200                         fi
1201                 fi
1202
1203                 binary=$1
1204
1205                 if [ x"$USE_GDB" = x"yes" ]; then
1206                         set -- gdb --args "$@"
1207                 elif [ x"$USE_GDB" = x"core" ] && which gdb >/dev/null 2>&1; then
1208                         set -- gdb --batch -x savecore.gdb --args "$@"
1209                 elif which catchsegv >/dev/null 2>&1; then
1210                         set -- catchsegv "$@"
1211                 fi
1212                 rm -f xonotic.core
1213                 "$@" || true
1214                 if [ -f xonotic.core ]; then
1215                         if yesno "The program has CRASHED. Do you want to examine the core dump?"; then
1216                                 gdb "$binary" xonotic.core
1217                         #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
1218                         #       tar cvzf xonotic.core.tar.gz xonotic.core darkplaces/*.c darkplaces/*.h
1219                         #       # somehow send it
1220                         #       rm -f xonotic.core.tar.gz
1221                         else
1222                                 $ECHO "The core dump can be examined later by"
1223                                 $ECHO "  gdb $binary xonotic.core"
1224                         fi
1225                         exit 1
1226                 fi
1227                 ;;
1228         each|foreach)
1229                 keep_going=false
1230                 if [ x"$1" = x"-k" ]; then
1231                         keep_going=true
1232                         shift
1233                 fi
1234                 for d in $repos; do
1235                         if verbose cd "$d0/$d"; then
1236                                 if $keep_going; then
1237                                         verbose "$@" || true
1238                                 else
1239                                         verbose "$@"
1240                                 fi
1241                                 cd "$d0"
1242                         fi
1243                 done
1244                 ;;
1245         save-patches)
1246                 outfile=$1
1247                 patchdir=`mktemp -d -t save-patches.XXXXXX`
1248                 for d in $repos; do
1249                         enter "$d0/$d" verbose
1250                         git branch -v -v | cut -c 3- | {
1251                                 i=0
1252                                 while read -r BRANCH REV UPSTREAM TEXT; do
1253                                         case "$UPSTREAM" in
1254                                                 \[*)
1255                                                         UPSTREAM=${UPSTREAM#\[}
1256                                                         UPSTREAM=${UPSTREAM%\]}
1257                                                         UPSTREAM=${UPSTREAM%:*}
1258                                                         TRACK=true
1259                                                         ;;
1260                                                 *)
1261                                                         UPSTREAM=origin/"`repobranch "$d"`"
1262                                                         TRACK=false
1263                                                         ;;
1264                                         esac
1265                                         if [ x"$REV" = x"->" ]; then
1266                                                 continue
1267                                         fi
1268                                         if git format-patch -o "$patchdir/$i" "$UPSTREAM".."$BRANCH"; then
1269                                                 $ECHO "$d" > "$patchdir/$i/info.txt"
1270                                                 $ECHO "$BRANCH" >> "$patchdir/$i/info.txt"
1271                                                 $ECHO "$UPSTREAM" >> "$patchdir/$i/info.txt"
1272                                                 $ECHO "$TRACK" >> "$patchdir/$i/info.txt"
1273                                                 i=$(($i+1))
1274                                         else
1275                                                 rm -rf "$patchdir/$i"
1276                                         fi
1277                                 done
1278                         }
1279                 done
1280                 ( cd "$patchdir" && tar cvzf - . ) > "$outfile"
1281                 rm -rf "$patchdir"
1282                 ;;
1283         restore-patches)
1284                 infile=$1
1285                 patchdir=`mktemp -d -t restore-patches.XXXXXX`
1286                 ( cd "$patchdir" && tar xvzf - ) < "$infile"
1287                 # detach the head
1288                 for P in "$patchdir"/*/info.txt; do
1289                         D=${P%/info.txt}
1290                         exec 3<"$P"
1291                         read -r d <&3
1292                         read -r BRANCH <&3
1293                         read -r UPSTREAM <&3
1294                         read -r TRACK <&3
1295                         verbose git checkout HEAD^0
1296                         verbose git branch -D "$BRANCH"
1297                         if [ x"$TRACK" = x"true" ]; then
1298                                 verbose git checkout --track -b "$BRANCH" "$UPSTREAM"
1299                         else
1300                                 verbose git branch -b "$BRANCH" "$UPSTREAM"
1301                         fi
1302                         verbose git am "$D"
1303                 done
1304                 rm -rf "$patchdir"
1305                 ;;
1306         admin-merge)
1307                 branch=$1
1308                 only_delete=false
1309                 case "$branch" in
1310                         -d)
1311                                 branch=
1312                                 only_delete=true
1313                                 ;;
1314                 esac
1315                 t=`mktemp`
1316                 report=""
1317                 reportecho()
1318                 {
1319                         report=$report"$*$LF"
1320                         $ECHO "$*"
1321                 }
1322                 reportecho4()
1323                 {
1324                         report=$report"    $*$LF"
1325                         $ECHO "    $*"
1326                 }
1327                 reportdo4()
1328                 {
1329                         o=`"$@" | sed 's/^/    /' || true`
1330                         reportecho "$o"
1331                 }
1332                 for d in $repos; do
1333                         case "$d" in
1334                                 fteqcc)
1335                                         # sorry, fteqcc repo is managed manually
1336                                         continue
1337                                         ;;
1338                         esac
1339                         enter "$d0/$d" verbose
1340                         base="`repobranch "$d"`"
1341                         reportecho "In $d:"
1342                         for ref in `git for-each-ref --format='%(refname)' refs/remotes/origin/`; do
1343                                 case "${ref#refs/remotes/origin/}" in
1344                                         "$base")
1345                                                 continue
1346                                                 ;;
1347                                         HEAD|master)
1348                                                 continue
1349                                                 ;;
1350                                         */*)
1351                                                 ;;
1352                                         *)
1353                                                 continue
1354                                                 ;;
1355                                 esac
1356                                 if [ -n "$branch" ]; then
1357                                         if [ x"$branch" != x"${ref#refs/remotes/origin/}" ]; then
1358                                                 continue
1359                                         fi
1360                                 fi
1361                                 case "$base" in
1362                                         master)
1363                                                 realbase=$base
1364                                                 ;;
1365                                         *)
1366                                                 l0=`git rev-list "$base".."$ref" | wc -l`
1367                                                 l1=`git rev-list master.."$ref" | wc -l`
1368                                                 if [ $l0 -gt $l1 ]; then
1369                                                         realbase=master
1370                                                 else
1371                                                         realbase=$base
1372                                                 fi
1373                                                 ;;
1374                                 esac
1375                                 reportecho "  Branch $ref:"
1376                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1377                                 logdata=`git log --color "$realbase".."$ref"`
1378                                 if [ -z "$logdata" ]; then
1379                                         reportecho4 "--> not merging, no changes vs master"
1380                                         if yesno "Branch \"$ref\" probably should get deleted. Do it?" ''; then
1381                                                 git push origin :"${ref#refs/remotes/origin/}"
1382                                                 reportecho4 "--> branch deleted"
1383                                         fi
1384                                 else
1385                                         diffdata=`git diff --color --find-copies-harder --ignore-space-change "$realbase"..."$ref"`
1386                                         if [ -z "$diffdata" ]; then
1387                                                 reportecho4 "--> not merging, no changes vs master, branch contains redundant history"
1388                                                 if yesno "Branch \"$ref\" probably should get deleted. Do it?" '{ $ECHO "$logdata"; } | less -r'; then
1389                                                         git push origin :"${ref#refs/remotes/origin/}"
1390                                                         reportecho4 "--> branch deleted"
1391                                                 fi
1392                                         elif $only_delete; then
1393                                                 reportecho4 "--> skipped in delete-only run"
1394                                         elif [ -z "$branch" ] && [ -n "$note" ]; then
1395                                                 reportdo4 $ECHO "$note"
1396                                                 reportecho4 "--> not merging, already had this one rejected before"
1397                                         elif yesno "Branch \"$ref\" may want to get merged. Do it?" '{ $ECHO "$logdata"; $ECHO "$diffdata"; } | less -r'; then
1398                                                 git checkout "$realbase"
1399                                                 org=`git rev-parse HEAD`
1400                                                 if ! git merge --no-ff "$ref" 2>&1 | tee "$t" && ! { git ls-files -u | grep ' 1 ' >/dev/null; }; then
1401                                                         git reset --hard "$org"
1402                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Merge failed:$LF`cat "$t"`" "$ref"
1403                                                         reportdo4 cat "$t"
1404                                                         reportecho4 "--> merge failed"
1405                                                 elif ! "$SELF" compile 2>&1 | tee "$t"; then
1406                                                         git reset --hard "$org"
1407                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit -m "Compile failed:$LF`cat "$t"`" "$ref"
1408                                                         reportdo4 cat "$t"
1409                                                         reportecho4 "--> compile failed"
1410                                                 elif ! yesno "Still merge \"$ref\" into `git symbolic-ref HEAD` of $d? Maybe you want to test first."; then
1411                                                         git reset --hard "$org"
1412                                                         GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1413                                                         note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1414                                                         if [ x"$note" = x"del" ]; then
1415                                                                 git push origin :"${ref#refs/remotes/origin/}"
1416                                                                 reportecho4 "--> test failed, branch deleted"
1417                                                         elif [ -n "$note" ]; then
1418                                                                 reportdo4 $ECHO "$note"
1419                                                                 reportecho4 "--> test failed"
1420                                                         else
1421                                                                 reportecho4 "--> test failed, postponed"
1422                                                         fi
1423                                                 else
1424                                                         # apply crlf, or other cleanup filters (non-behavioural changes)
1425                                                         git reset --hard
1426                                                         find . -type f -exec touch {} \;
1427                                                         git commit -a --amend -C HEAD || true # don't fail if nothing to commit
1428
1429                                                         $ECHO "MERGING"
1430                                                         case ",`repoflags "$d"`," in
1431                                                                 *,svn,*)
1432                                                                         # we do quite a mess here... luckily we know $org
1433                                                                         git fetch # svn needs to be current
1434                                                                         git rebase -i --onto origin/master "$org"
1435                                                                         git svn dcommit --add-author-from
1436                                                                         git reset --hard "$org"
1437                                                                         ;;
1438                                                                 *)
1439                                                                         git push origin HEAD
1440                                                                         ;;
1441                                                         esac
1442                                                         reportecho4 "--> MERGED"
1443                                                         if yesno "Delete original branch \"$ref\"?"; then
1444                                                                 git push origin :"${ref#refs/remotes/origin/}"
1445                                                                 reportecho4 "--> branch deleted"
1446                                                         fi
1447                                                 fi
1448                                         else
1449                                                 GIT_NOTES_REF=refs/notes/admin-merge git notes edit "$ref"
1450                                                 note=`GIT_NOTES_REF=refs/notes/admin-merge git notes show "$ref" 2>/dev/null || true`
1451                                                 if [ x"$note" = x"del" ]; then
1452                                                         git push origin :"${ref#refs/remotes/origin/}"
1453                                                         reportecho4 "--> branch deleted"
1454                                                 elif [ -n "$note" ]; then
1455                                                         reportdo4 $ECHO "$note"
1456                                                         reportecho4 "--> rejected"
1457                                                 else
1458                                                         reportecho4 "--> postponed"
1459                                                 fi
1460                                         fi
1461                                 fi
1462                                 reportecho ""
1463                         done
1464                         reportecho ""
1465                 done
1466                 rm -f "$t"
1467                 $ECHO "$report" | ssh nexuiz@rm.endoftheinternet.org cat '>>' public_html/xonotic-merge-notes.txt
1468                 ;;
1469         clean)
1470                 "$SELF" fix_config
1471                 "$SELF" update -N
1472                 force=false
1473                 gotoupstream=false
1474                 fetchupstream=false
1475                 gotomaster=false
1476                 rmuntracked=false
1477                 killbranches=false
1478                 # usage:
1479                 #   ./all clean [-m] [-f | -fu | -fU] [-r] [-D]
1480                 #   ./all clean --reclone
1481                 found=false
1482                 for X in "$@"; do
1483                         if [ x"$X" = x"--reclone" ]; then
1484                                 force=true
1485                                 fetchupstream=true
1486                                 gotoupstream=true
1487                                 gotomaster=true
1488                                 rmuntracked=true
1489                                 killbranches=true
1490                         elif [ x"$X" = x"-f" ]; then
1491                                 force=true
1492                         elif [ x"$X" = x"-u" ]; then
1493                                 gotoupstream=true
1494                         elif [ x"$X" = x"-U" ]; then
1495                                 gotoupstream=true
1496                                 fetchupstream=true
1497                         elif [ x"$X" = x"-fu" ]; then
1498                                 force=true
1499                                 gotoupstream=true
1500                         elif [ x"$X" = x"-fU" ]; then
1501                                 force=true
1502                                 gotoupstream=true
1503                                 fetchupstream=true
1504                         elif [ x"$X" = x"-m" ]; then
1505                                 gotomaster=true
1506                         elif [ x"$X" = x"-r" ]; then
1507                                 rmuntracked=true
1508                         elif [ x"$X" = x"-D" ]; then
1509                                 killbranches=true
1510                         elif $ECHO "$X" | grep '^-FFFF*UUUU*$' >/dev/null; then
1511                                 msg ''
1512                                 msg "        _____"
1513                                 msg "    ,--'-\\P/\`\\  FFFFFFF"
1514                                 msg " __/_    B/,-.\\  FFFFFFF"
1515                                 msg " /  _\\  (//  O\\\\  FFFFFF"
1516                                 msg "| (O  \`) _\\._ _)\\  FFFUU"
1517                                 msg "| |___/.^d0~~\"\\  \\ UUUU"
1518                                 msg "|     |\`~'     \\ |  UUUU"
1519                                 msg "|     |    __,C>|| UUUU"
1520                                 msg "\\    /_ ,-/,-'   |  UUUU"
1521                                 msg " \\\\_ \\_>~'      /  UUUU-"
1522                                 msg ''
1523                         else
1524                                 msg "Unknown arg: $X"
1525                         fi
1526                         found=true
1527                 done
1528                 if ! $found; then
1529                         rmuntracked=true
1530                 fi
1531                 for d in $repos; do
1532                         verbose cd "$d0/$d"
1533                         if $gotoupstream; then
1534                                 if ! $force; then
1535                                         msg "Must also use -f (delete local changes) when using -u"
1536                                         exit 1
1537                                 fi
1538                                 if $gotomaster; then
1539                                         if $fetchupstream; then
1540                                                 verbose git fetch origin
1541                                                 verbose git remote prune origin
1542                                         fi
1543                                         verbose git checkout -f "`repobranch "$d"`"
1544                                         verbose git reset --hard origin/"`repobranch "$d"`"
1545                                 else
1546                                         r=`git symbolic-ref HEAD`
1547                                         r=${r#refs/heads/}
1548                                         rem=`git config "branch.$r.remote" || $ECHO origin`
1549                                         bra=`git config "branch.$r.merge" || $ECHO "$r"`
1550                                         upstream="$rem/${bra#refs/heads/}"
1551                                         if $fetchupstream; then
1552                                                 verbose git fetch "$rem"
1553                                                 verbose git remote prune "$rem"
1554                                         fi
1555                                         if ! git rev-parse "$upstream" >/dev/null 2>&1; then
1556                                                 upstream="origin/`repobranch "$d"`"
1557                                         fi
1558                                         verbose git reset --hard "$upstream"
1559                                 fi
1560                         elif $gotomaster; then
1561                                 if $force; then
1562                                         verbose git checkout -f "`repobranch "$d"`"
1563                                         verbose git reset --hard
1564                                 else
1565                                         verbose git checkout "`repobranch "$d"`"
1566                                 fi
1567                         elif $force; then
1568                                 verbose git reset --hard
1569                         fi
1570                         if $rmuntracked; then
1571                                 case "$d" in
1572                                         .)
1573                                                 verbose git clean -df || true
1574                                                 ;;
1575                                         *)
1576                                                 verbose git clean -xdf || true
1577                                                 ;;
1578                                 esac
1579                         fi
1580                         if $killbranches; then
1581                                 git for-each-ref --format='%(refname)' refs/heads/ | while IFS= read -r B; do
1582                                         if [ x"$B" != x"`git symbolic-ref HEAD`" ]; then
1583                                                 verbose git branch -D "${B#refs/heads/}"
1584                                         fi
1585                                 done
1586                                 git rev-parse refs/heads/master >/dev/null 2>&1 || verbose git branch --track master origin/master || true
1587                                 git rev-parse "refs/heads/`repobranch "$d"`" >/dev/null 2>&1 || verbose git branch --track "`repobranch "$d"`" origin/"`repobranch "$d"`" || true
1588                         fi
1589                         checkself "$cmd" "$@"
1590                 done
1591                 ;;
1592
1593         # release building goes here
1594         release-prepare)
1595                 #"$SELF" each git clean -fxd
1596                 case "$RELEASETYPE" in
1597                         '')
1598                                 $ECHO >&2 -n "$ESC[2J$ESC[H"
1599                                 msg ""
1600                                 msg ""
1601                                 msg ""
1602                                 msg ""
1603                                 msg ""
1604                                 msg ""
1605                                 msg "        +---------------------------------------------------------.---+"
1606                                 msg "        | NOTE                                                    | X |"
1607                                 msg "        +---------------------------------------------------------^---+"
1608                                 msg "        |   ____                                                      |"
1609                                 msg "        |  /    \  This is the official release build system.         |"
1610                                 msg "        | |      | If you are not a member of the Xonotic Core Team,  |"
1611                                 msg "        | | STOP | you are not supposed to use this script and should |"
1612                                 msg "        | |      | instead use ./all compile to compile the engine    |"
1613                                 msg "        |  \____/  and game code.                                     |"
1614                                 msg "        |                                                             |"
1615                                 msg "        |                      [ I understand ]                       |"
1616                                 msg "        +-------------------------------------------------------------+"
1617                                 sleep 10
1618                                 # A LOT of build infrastructure is required:
1619                                 # - vorbis-tools
1620                                 # - ImageMagick
1621                                 # - .ssh/config must be configured so the following
1622                                 #   host names are reachable and have a compile
1623                                 #   infrastructure set up:
1624                                 #   - xonotic-build-linux32 (with gcc on x86)
1625                                 #   - xonotic-build-linux64 (with gcc on x86_64)
1626                                 #   - xonotic-build-win32 (with i586-mingw32msvc-g++)
1627                                 #   - xonotic-build-win64 (with amd64-mingw32msvc-g++
1628                                 #     and x86_64-w64-mingw32-g++)
1629                                 #   - xonotic-build-osx (with Xcode and SDL.framework)
1630                                 # - AMD Compressonator installed in WINE
1631                                 # - ResEdit installed in WINE
1632                                 # - a lot of other requirements you will figure out
1633                                 #   while reading the error messages
1634                                 # - environment variable RELEASETYPE set
1635                                 # - optionally, environment variable RELEASEDATE set
1636                                 #   (YYYYMMDD)
1637                                 exit 1
1638                                 ;;
1639                         release)
1640                                 msg "Building a FINISHED RELEASE"
1641                                 ;;
1642                         *)
1643                                 msg "Building a $RELEASETYPE"
1644                                 ;;
1645                 esac
1646                 verbose rm -rf Xonotic Xonotic*.zip
1647                 verbose mkdir -p Xonotic
1648                 if [ -n "$RELEASEDATE" ]; then
1649                         verbose $ECHO "$RELEASEDATE" > Xonotic/stamp.txt
1650                 else
1651                         verbose date +%Y%m%d > Xonotic/stamp.txt
1652                 fi
1653                 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
1654                 (
1655                         verbose cd Xonotic
1656                         verbose mkdir data fteqcc source source/darkplaces source/fteqcc source/d0_blind_id mapping
1657                         verbose rm -rf misc/builddeps
1658                         verbose mv misc/buildfiles/win32 bin32 || true
1659                         verbose mv bin32/SDL.dll . || true
1660                         verbose mv misc/buildfiles/win64 bin64 || true
1661                         verbose mv misc/buildfiles/osx/* . || true
1662                         verbose rm -rf misc/buildfiles
1663                         verbose rm -rf misc/pki
1664                 )
1665                 release_git_extract_dir "darkplaces" "Xonotic/source/darkplaces" .
1666                 release_git_extract_dir "fteqcc" "Xonotic/source/fteqcc" .
1667                 release_git_extract_dir "data/xonotic-data.pk3dir" "Xonotic/source" qcsrc Makefile
1668                 release_git_extract_dir "d0_blind_id" "Xonotic/source/d0_blind_id" .
1669                 (
1670                         verbose cd Xonotic/source/d0_blind_id
1671                         verbose sh autogen.sh
1672                 )
1673                 rm -f Xonotic/key_15.d0pk
1674                 {
1675                         verbose cd Xonotic/mapping
1676                         verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20110819.tar.bz2
1677                         verbose wget http://www.icculus.org/netradiant/files/netradiant-1.5.0-20110819-win32-7z.exe
1678                         for X in *-7z.exe; do
1679                                 7za x "$X"
1680                                 rm -f "$X"
1681                         done
1682                         # TODO possibly include other tools?
1683                 }
1684                 ;;
1685         release-compile-run)
1686                 host=$1
1687                 buildpath=$2
1688                 maketargets=$3
1689                 makeflags=$4
1690                 srcdir=$5
1691                 depsdir=$6
1692                 targetfiles=$7
1693                 set -x
1694                 if [ -n "$targetfiles" ]; then
1695                         case " $HOSTS_THAT_ARE_DISABLED " in
1696                                 *\ $host\ *)
1697                                         exit
1698                                         ;;
1699                         esac
1700                         case " $HOSTS_THAT_ARE_MYSELF " in
1701                                 *\ $host\ *)
1702                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$buildpath/"
1703                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$buildpath.deps/"
1704                                         verbose ln -snf "$buildpath.deps" "$buildpath/.deps"
1705                                         verbose eval make -C "$buildpath" clean $maketargets $makeflags
1706                                         for f in $targetfiles; do
1707                                                 verbose mv "$buildpath/${f%:*}" "${f##*:}" || true
1708                                         done
1709                                         ;;
1710                                 *)
1711                                         verbose rsync --delete -zLvaSHP "$srcdir"/ "$host:$buildpath/"
1712                                         verbose rsync --delete -zLvaSHP "$depsdir"/ "$host:$buildpath.deps/"
1713                                         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"
1714                                         for f in $targetfiles; do
1715                                                 verbose rsync -zvaSHP "$host:$buildpath/${f%:*}" "${f##*:}" || true
1716                                         done
1717                                         ;;
1718                         esac
1719                         # now rebrand the binaries...
1720                         for f in $targetfiles; do
1721                                 #verbose "$d0/misc/tools/rebrand-darkplaces-engine.sh" "${XONOTIC_BRAND:-$d0/misc/tools/xonotic.brand}" "${f##*:}" || true
1722                                 case "${f##*:}" in
1723                                         Xonotic/xonotic*.exe)
1724                                                 verbose "$d0/misc/tools/change-icon-of-exe.sh" "$d0/misc/logos/icons_ico/xonotic.ico" "${f##*:}"
1725                                                 ;;
1726                                 esac
1727                         done
1728                 fi
1729                 ;;
1730         release-compile)
1731                 suffix=$1
1732                 makeflags=$2
1733                 fteqcc_maketargets=$3
1734                 fteqcc_files=$4
1735                 darkplaces_maketargets=$5
1736                 darkplaces_files=$6
1737                 host=xonotic-build-$suffix
1738                 verbose "$SELF" release-compile-run "$host" /tmp/fteqcc.build."$suffix" "$fteqcc_maketargets" "$makeflags" "Xonotic/source/fteqcc" "$d0/misc/builddeps/dp.$suffix" "$fteqcc_files"
1739                 verbose "$SELF" release-compile-run "$host" /tmp/Darkplaces.build."$suffix" "$darkplaces_maketargets" "$makeflags" "Xonotic/source/darkplaces" "$d0/misc/builddeps/dp.$suffix" "$darkplaces_files"
1740                 ;;
1741         release-engine-win32)
1742                 verbose "$SELF" release-compile win32 \
1743                         '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' \
1744                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc.exe' \
1745                         '' ''
1746                 verbose "$SELF" release-compile win32 \
1747                         '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' \
1748                         '' '' \
1749                         release 'darkplaces.exe:Xonotic/xonotic.exe darkplaces-sdl.exe:Xonotic/xonotic-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-dedicated.exe'
1750                 ;;
1751         release-engine-win64)
1752                 verbose "$SELF" release-compile win64 \
1753                         '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' \
1754                         win 'fteqcc.exe:Xonotic/fteqcc/fteqcc-x64.exe' \
1755                         'sv-release sdl-release' 'darkplaces-sdl.exe:Xonotic/xonotic-x64-sdl.exe darkplaces-dedicated.exe:Xonotic/xonotic-x64-dedicated.exe'
1756                 verbose "$SELF" release-compile win64 \
1757                         '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' \
1758                         '' '' \
1759                         cl-release 'darkplaces.exe:Xonotic/xonotic-x64.exe'
1760                 ;;
1761         release-engine-osx)
1762                 # gcc on OSX is buggy, needs -fno-reorder-blocks for a release build to succeed
1763                 verbose "$SELF" release-compile osx \
1764                         '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"' \
1765                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.osx' \
1766                         'sv-release sdl-release' 'darkplaces-sdl:Xonotic/Xonotic.app/Contents/MacOS/xonotic-osx-sdl-bin darkplaces-dedicated:Xonotic/xonotic-osx-dedicated'
1767                 ;;
1768         release-engine-linux32)
1769                 verbose "$SELF" release-compile linux32 \
1770                         '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' \
1771                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux32' \
1772                         release 'darkplaces-glx:Xonotic/xonotic-linux32-glx darkplaces-sdl:Xonotic/xonotic-linux32-sdl darkplaces-dedicated:Xonotic/xonotic-linux32-dedicated'
1773                 ;;
1774         release-engine-linux64)
1775                 verbose "$SELF" release-compile linux64 \
1776                         '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' \
1777                         all 'fteqcc.bin:Xonotic/fteqcc/fteqcc.linux64' \
1778                         release 'darkplaces-glx:Xonotic/xonotic-linux64-glx darkplaces-sdl:Xonotic/xonotic-linux64-sdl darkplaces-dedicated:Xonotic/xonotic-linux64-dedicated'
1779                 ;;
1780         release-engine)
1781                 verbose "$SELF" release-engine-linux32 &
1782                 verbose "$SELF" release-engine-linux64 &
1783                 verbose "$SELF" release-engine-win32 &
1784                 verbose "$SELF" release-engine-win64 &
1785                 verbose "$SELF" release-engine-osx &
1786                 wait %1
1787                 wait %2
1788                 wait %3
1789                 wait %4
1790                 wait %5
1791                 wait
1792                 ;;
1793         release-maps)
1794                 verbose "$SELF" update-maps
1795                 ;;
1796         release-qc)
1797                 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
1798                 verbose rm -f Xonotic/source/qcsrc/*/fteqcc.log
1799                 ;;
1800         release-buildpk3-transform-raw)
1801                 dir=$1
1802                 ;;
1803         release-buildpk3-transform-normal)
1804                 dir=$1
1805                 verbose cd "$dir"
1806                 # texture: convert to jpeg and dds
1807                 verbose export do_jpeg=true
1808                 verbose export jpeg_qual_rgb=97
1809                 verbose export jpeg_qual_a=99
1810                 verbose export do_dds=false
1811                 verbose export do_ogg=false
1812                 verbose export del_src=true
1813                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1814                 ;;
1815         release-buildpk3-transform-normaldds)
1816                 dir=$1
1817                 verbose cd "$dir"
1818                 # texture: convert to jpeg and dds
1819                 # music: reduce bitrate
1820                 verbose export do_jpeg=false
1821                 verbose export do_jpeg_if_not_dds=true
1822                 verbose export jpeg_qual_rgb=95
1823                 verbose export jpeg_qual_a=99
1824                 verbose export do_dds=true
1825                 verbose export dds_flags=
1826                 verbose export do_ogg=true
1827                 verbose export del_src=true
1828                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1829                 ;;
1830         release-buildpk3-transform-low)
1831                 dir=$1
1832                 verbose cd "$dir"
1833                 # texture: convert to jpeg and dds
1834                 # music: reduce bitrate
1835                 verbose export do_jpeg=true
1836                 verbose export jpeg_qual_rgb=80
1837                 verbose export jpeg_qual_a=97
1838                 verbose export do_dds=false
1839                 verbose export do_ogg=true
1840                 verbose export ogg_qual=1
1841                 verbose export del_src=true
1842                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1843                 ;;
1844         release-buildpk3-transform-lowdds)
1845                 dir=$1
1846                 verbose cd "$dir"
1847                 # texture: convert to jpeg and dds
1848                 # music: reduce bitrate
1849                 verbose export do_jpeg=false
1850                 verbose export do_jpeg_if_not_dds=true
1851                 verbose export jpeg_qual_rgb=80
1852                 verbose export jpeg_qual_a=99
1853                 verbose export do_dds=true
1854                 verbose export dds_flags=
1855                 verbose export do_ogg=true
1856                 verbose export ogg_qual=1
1857                 verbose export del_src=true
1858                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1859                 ;;
1860         release-buildpk3-transform-mapping)
1861                 dir=$1
1862                 verbose cd "$dir"
1863                 # remove stuff radiant has no use for
1864                 verbose find . -name \*_norm.\* -exec rm -f {} \;
1865                 verbose find . -name \*_bump.\* -exec rm -f {} \;
1866                 verbose find . -name \*_glow.\* -exec rm -f {} \;
1867                 verbose find . -name \*_gloss.\* -exec rm -f {} \;
1868                 verbose find . -name \*_pants.\* -exec rm -f {} \;
1869                 verbose find . -name \*_shirt.\* -exec rm -f {} \;
1870                 verbose find . -name \*_reflect.\* -exec rm -f {} \;
1871                 verbose find . -not \( -name \*.tga -o -name \*.png -o -name \*.jpg \) -exec rm -f {} \;
1872                 # texture: convert to jpeg and dds
1873                 # music: reduce bitrate
1874                 verbose export do_jpeg=true
1875                 verbose export jpeg_qual_rgb=80
1876                 verbose export jpeg_qual_a=97
1877                 verbose export do_dds=false
1878                 verbose export do_ogg=true
1879                 verbose export ogg_qual=1
1880                 verbose export del_src=true
1881                 find . -type f -print0 | verbose xargs -0 "$d0"/misc/tools/cached-converter.sh
1882                 ;;
1883         release-buildpk3)
1884                 src=$1
1885                 dst=$2
1886                 transform=$3
1887                 case "$dst" in
1888                         /*)
1889                                 ;;
1890                         */)
1891                                 dst="$PWD/$dst"
1892                                 ;;
1893                 esac
1894                 release_timereport
1895                 verbose rm -rf Xonotic/temp
1896                 release_timereport "deleted temp directory"
1897                 verbose mkdir -p Xonotic/temp
1898                 release_git_extract_dir "$src" "Xonotic/temp" .
1899                 release_timereport "extracted data"
1900                 verbose cd Xonotic/temp
1901                 if [ x"$src" = x"data/xonotic-data.pk3dir" ]; then
1902                         verbose cp ../source/progs.dat .
1903                         verbose cp ../source/csprogs.dat .
1904                         verbose cp ../source/menu.dat .
1905                         verbose rm -rf qcsrc
1906                         gv=`grep "^gameversion " "defaultXonotic.cfg" | awk '{ print $2 }'`
1907                         major=$(($gv / 10000))
1908                         minor=$((($gv / 100) - ($major * 100)))
1909                         patch=$(($gv - ($major * 10000) - ($minor * 100)))
1910                         versionstr="$major.$minor.$patch"
1911                         case "$RELEASETYPE" in
1912                                 release)
1913                                         ;;
1914                                 *)
1915                                         versionstr="$versionstr$RELEASETYPE"
1916                                         ;;
1917                         esac
1918                         if [ $gv -lt 9900 ]; then
1919                                 # pre-1.0: compatible with any other pre-1.0
1920                                 verbose sed "
1921                                         s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1922                                         s/^gameversion_min [0-9]*/gameversion_min     0/;
1923                                         s/^gameversion_max [0-9]*/gameversion_max  9999/;
1924                                 " < defaultXonotic.cfg > defaultXonotic.cfg.new
1925                         else
1926                                 # >= 1.0
1927                                 verbose sed "
1928                                         s/^set g_xonoticversion [^ ]* /set g_xonoticversion $versionstr /;
1929                                         s/^gameversion_min [0-9]*/gameversion_min $(( ($gv / 100) * 100 - 100 ))/;
1930                                         s/^gameversion_max [0-9]*/gameversion_max $(( ($gv / 100) * 100 + 199 ))/;
1931                                 " < defaultXonotic.cfg > defaultXonotic.cfg.new
1932                         fi
1933                         mv defaultXonotic.cfg.new defaultXonotic.cfg
1934                         case "$RELEASETYPE" in
1935                                 release)
1936                                         echo "" >> defaultXonotic.cfg
1937                                         echo "// nicer menu" >> defaultXonotic.cfg
1938                                         echo "set menu_watermark \"\"" >> defaultXonotic.cfg
1939                                         ;;
1940                         esac
1941                         (
1942                                 verbose cd gfx/menu/luminos
1943                                 verbose rm -f background_l2.tga background_ingame_l2.tga
1944                                 verbose cp "$d0"/mediasource/gfx/menu/luminos_versionbuilder/background_l2.svg .
1945                                 verbose "$d0"/mediasource/gfx/menu/luminos_versionbuilder/versionbuilder "$versionstr"
1946                                 verbose rm background_l2.svg
1947                         )
1948                 fi
1949                 if [ x"$src" = x"data/xonotic-maps.pk3dir" ]; then
1950                         for X in ../../data/*-????????????????????????????????????????-????????????????????????????????????????.pk3; do
1951                                 if [ -f "$X" ]; then
1952                                         verbose unzip "$X"
1953                                         verbose rm -f maps/*.log maps/*.irc maps/*.lin
1954                                 fi
1955                         done
1956                 fi
1957                 verbose export git_src_repo="$d0/$src" # skip hash-object
1958                 release_timereport "processed data"
1959                 verbose "$SELF" release-buildpk3-transform-$transform "Xonotic/temp"
1960                 release_timereport "transformed data"
1961                 find . -type f -size +4k | verbose "$d0"/misc/tools/symlink-deduplicate.sh
1962                 release_timereport "deduplicated data"
1963                 verbose mkzipr "../../$dst" *
1964                 release_timereport "zipped data"
1965                 verbose cd ../..
1966                 verbose rm -rf Xonotic/temp
1967                 release_timereport "deleted temp directory again"
1968                 ;;
1969         release-buildpk3s)
1970                 stamp=`cat Xonotic/stamp.txt`
1971                 src=$1
1972                 shift
1973                 dst=${src%.pk3dir}
1974                 case "$dst" in
1975                         data/xonotic-*)
1976                                 dst="data/xonotic-$stamp-${dst#data/xonotic-}"
1977                                 ;;
1978                         *)
1979                                 dst="$dst-$stamp"
1980                                 ;;
1981                 esac
1982                 while [ "$#" -gt 1 ]; do
1983                         verbose "$SELF" release-buildpk3 "$src" "Xonotic/$dst$2.pk3" "$1"
1984                         shift
1985                         shift
1986                 done
1987                 ;;
1988         release-pack)
1989                 verbose "$SELF" release-buildpk3s data/font-nimbussansl.pk3dir                  raw ''
1990                 verbose "$SELF" release-buildpk3s data/font-xolonium.pk3dir                     raw ''
1991                 verbose "$SELF" release-buildpk3s data/xonotic-data.pk3dir       normal '-high'        low '-low' normaldds ''
1992                 verbose "$SELF" release-buildpk3s data/xonotic-maps.pk3dir       normal '-high'        low '-low' normaldds '' mapping '-mapping'
1993                 verbose "$SELF" release-buildpk3s data/xonotic-music.pk3dir                     raw '' low '-low'
1994                 verbose "$SELF" release-buildpk3s data/xonotic-nexcompat.pk3dir  normal '-high'                   normaldds ''
1995                 ;;
1996         release-pack-needsx11)
1997                 case "$DISPLAY" in
1998                         '')
1999                                 verbose startx "$SELF" release-pack -- /usr/bin/Xvfb :7
2000                                 ;;
2001                         *)
2002                                 verbose "$SELF" release-pack
2003                                 ;;
2004                 esac
2005                 ;;
2006         release-zip)
2007                 stamp=`cat Xonotic/stamp.txt`
2008                 # exe and dll files do not need +x, so this makes them eligible for 7zip compression too
2009                 chmod a-x Xonotic/*.exe Xonotic/*.dll || true
2010                 # let's pass crypto import laws of some nasty countries
2011                 crypto_libs=`find Xonotic -name \*d0_rijndael\*.so -o -name \*d0_rijndael\*.dylib -o -name \*d0_rijndael\*.dll -o -name \*d0_rijndael\*.c`
2012                 if [ -n "$crypto_libs" ]; then
2013                         verbose mkzip Xonotic-$stamp-crypto.zip \
2014                                 $crypto_libs \
2015                                 Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
2016                         rm -f $crypto_libs
2017                 fi
2018                 # build the archives
2019                 verbose mkzip Xonotic-$stamp-enginesource.zip \
2020                         Xonotic/source/darkplaces/ \
2021                         Xonotic/COPYING Xonotic/GPL-2 Xonotic/GPL-3
2022                 verbose cp Xonotic-$stamp-enginesource.zip Xonotic-$stamp-engine.zip
2023                 verbose mkzip Xonotic-$stamp-engine.zip \
2024                         Xonotic/*.dll \
2025                         Xonotic/bin32/*.dll \
2026                         Xonotic/bin64/*.dll \
2027                         Xonotic/*.app \
2028                         Xonotic/xonotic-* \
2029                         Xonotic/xonotic.exe
2030                 verbose cp Xonotic-$stamp-engine.zip Xonotic-$stamp-common.zip
2031                 verbose mkzip Xonotic-$stamp-common.zip \
2032                         Xonotic/source/fteqcc/ \
2033                         Xonotic/source/qcsrc/ \
2034                         Xonotic/Docs \
2035                         Xonotic/misc \
2036                         Xonotic/fteqcc \
2037                         Xonotic/server \
2038                         Xonotic/key_0.d0pk \
2039                         Xonotic/data/font-nimbussansl-$stamp.pk3 \
2040                         Xonotic/data/font-xolonium-$stamp.pk3
2041                 verbose cp Xonotic-$stamp-enginesource.zip Xonotic-$stamp-source.zip
2042                 verbose mkzip Xonotic-$stamp-source.zip \
2043                         Xonotic/source/fteqcc/ \
2044                         Xonotic/source/qcsrc/ \
2045                         Xonotic/misc/logos
2046                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp.zip
2047                 verbose mkzip0 Xonotic-$stamp.zip \
2048                         Xonotic/data/xonotic-$stamp-data.pk3 \
2049                         Xonotic/data/xonotic-$stamp-maps.pk3 \
2050                         Xonotic/data/xonotic-$stamp-music.pk3 \
2051                         Xonotic/data/xonotic-$stamp-nexcompat.pk3
2052                 verbose cp Xonotic-$stamp-common.zip Xonotic-$stamp-low.zip
2053                 verbose mkzip0 Xonotic-$stamp-low.zip \
2054                         Xonotic/data/xonotic-$stamp-data-low.pk3 \
2055                         Xonotic/data/xonotic-$stamp-maps-low.pk3 \
2056                         Xonotic/data/xonotic-$stamp-music-low.pk3
2057                 verbose mv Xonotic-$stamp-common.zip Xonotic-$stamp-high.zip
2058                 verbose mkzip Xonotic-$stamp-high.zip \
2059                         Xonotic/mapping
2060                 verbose mkzip0 Xonotic-$stamp-high.zip \
2061                         Xonotic/data/xonotic-$stamp-data-high.pk3 \
2062                         Xonotic/data/xonotic-$stamp-maps-high.pk3 \
2063                         Xonotic/data/xonotic-$stamp-music.pk3 \
2064                         Xonotic/data/xonotic-$stamp-nexcompat-high.pk3
2065                 verbose mkzip Xonotic-$stamp-mappingsupport.zip \
2066                         Xonotic/mapping
2067                 verbose mkzip0 Xonotic-$stamp-mappingsupport.zip \
2068                         Xonotic/data/xonotic-$stamp-maps-mapping.pk3
2069                 ;;
2070         release)
2071                 verbose "$SELF" release-prepare
2072                 verbose "$SELF" release-maps
2073                 verbose "$SELF" release-engine
2074                 verbose "$SELF" release-qc
2075                 verbose "$SELF" release-pack-needsx11
2076                 verbose "$SELF" release-zip
2077                 ;;
2078
2079         *)
2080                 $ECHO "Usage:"
2081                 $ECHO "  $SELF admin-merge [<branch>]"
2082                 $ECHO "  $SELF branch <branch>"
2083                 $ECHO "  $SELF branch <remote> <branch> [<srcbranch>]"
2084                 $ECHO "  $SELF branches"
2085                 $ECHO "  $SELF checkout|switch <branch>"
2086                 $ECHO "  $SELF checkout|switch <remote>/<branch>"
2087                 $ECHO "  $SELF clean [-m] [-f | -fu | -fU] [-r] [-D]"
2088                 $ECHO "  $SELF clean --reclone"
2089                 $ECHO "  $SELF compile [-c] [-r|-p] [-0] [sdl|glx|wgl|agl|dedicated]"
2090                 $ECHO "  $SELF each|foreach [-k] command..."
2091                 $ECHO "  $SELF fix_upstream_rebase"
2092                 $ECHO "  $SELF keygen"
2093                 $ECHO "  $SELF merge"
2094                 $ECHO "  $SELF push|commit [-s]"
2095                 $ECHO "  $SELF restore-patches"
2096                 $ECHO "  $SELF run [sdl|glx|wgl|agl|dedicated] options..."
2097                 $ECHO "  $SELF save-patches"
2098                 $ECHO "  $SELF update-maps"
2099                 $ECHO "  $SELF update|pull [-N] [-s | -h [-p] | -g [-p]] [-l de|nl|default]"
2100                 ;;
2101 esac