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