+#! /bin/sh -e
+
+fail () {
+ echo >&2 "$0: $*"
+ exit 1
+}
+
+usage () {
+ echo "usage: $0 [-c] [UPSTREAM BUILDABLE]"
+}
+
+fail_usage () {
+ usage >&2
+ exit 1
+}
+
+## Parse the command-line.
+bogusp=nil createp=nil
+unset head new
+while getopts "ch" opt; do
+ case $opt in
+ h) usage; exit 0 ;;
+ c) createp=t ;;
+ *) bogusp=t ;;
+ esac
+done
+shift $(( $OPTIND - 1 ))
+case $# in 0) ;; 1) bogusp=t ;; *) head=$1 new=$2; shift 2 ;; esac
+case $# in 0) ;; *) bogusp=t ;; esac
+case $bogusp in nil) ;; *) fail_usage ;; esac
+
+## Get the current branch name.
+case ${head+t} in
+ t) ;;
+ *)
+ head=$(git symbolic-ref HEAD)
+ case $head in
+ refs/heads/*) head=${head#refs/heads/} ;;
+ *) fail "HEAD is not at a branch head" ;;
+ esac
+ case $head in
+ buildable/*) fail "upstream is already a buildable branch" ;;
+ esac
+ ;;
+esac
+
+## Get the output branch name.
+case ${new+t} in
+ t) ;;
+ *)
+ new=buildable/$head
+ ;;
+esac
+case $createp in
+ t)
+ if git rev-parse $new -- >/dev/null 2>&1; then
+ fail "branch $new already exists"
+ fi
+ old=0000000000000000000000000000000000000000
+ ;;
+ nil)
+ old=$(git rev-parse $new --)
+ ;;
+esac
+
+## Make a temporary place.
+git=$(git rev-parse --git-dir)
+git=$(cd $git && pwd)
+dir=$(mktemp -d)
+trap "cd; rm -rf \"$dir\"" EXIT INT TERM
+cd "$dir"
+mkdir work tmp
+
+## Make a nice clean checkout.
+GIT_INDEX_FILE=$dir/idx; export GIT_INDEX_FILE
+GIT_DIR=$git; export GIT_DIR
+GIT_WORK_TREE=$dir/work; export GIT_WORK_TREE
+git read-tree "$head^{}"
+git checkout-index --all
+
+## Go in, and set stuff up. The business with `RELEASE' is kinda scungy.
+## Sorry 'bout that.
+cd work
+if ! ver=$(git describe --abbrev=4 "$head^{}" 2>/dev/null); then
+ ver=UNKNOWN
+fi
+echo "$ver" >RELEASE
+mdw-setup
+rm -rf autom4te.cache/ RELEASE
+
+## Pick through newly added symlinks and snap them to real files.
+git ls-files -o | while read f; do
+ if [ -L "$f" ]; then
+ cp "$f" ../tmp/snap
+ mv ../tmp/snap "$f"
+ fi
+done
+
+## Add the new files to the tree.
+commit () {
+ tree=$1; shift
+ case $createp in
+ t) git commit-tree -p "$head^{}" "$@" $tree ;;
+ nil) git commit-tree -p "$new" -p "$head^{}" "$@" $tree ;;
+ esac
+}
+git ls-files -oz | xargs -0r git add -f
+tree=$(git write-tree)
+commit=$(commit $tree -m "Update automatically managed build utilities.")
+git update-ref "refs/heads/$new" $commit $old