#!/usr/local/bin/zsh # Copyright (c) 2008 Sean Farley # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # 1. Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # This is a utility to commit to a primary SVN repository from another or even # multiple repositories as long as the UUID for all is the same. It performs # the necessary steps to do this: switching to the primary repository, updating # the tree, committing and syncing the local repository. # Switch repository root from local/remote to remote/local. switch_repo_root() { # Determine direction to switch (0 is to the primary, 1 is to the # mirror). ndx=${1} if [ ${2} -eq 0 ] then from=${LOCALURL[${ndx}]} to=${FBURL[${ndx}]} else from=${FBURL[${ndx}]} to=${LOCALURL[${ndx}]} fi echo "Switching ${ARGS[${ndx}]} to ${to}." svn switch --relocate ${from} ${to} ${ARGS[${ndx}]} return } # Clean up method called at exit. cleanup() { for ((ndx=1; ndx <= ${#ARGS}; ndx++)) do switch_repo_root ${ndx} 1 done return } # # MAIN # # Verify working within a repo. msg=`svn info "${@}" 2>&1` if [ ${?} -eq 1 ] then echo ${msg} exit fi # Retrieve the primary repo's UUID for checking against local repo(s). FBREPO="svn+ssh://svn.freebsd.org/base" FBREPOUUID=`svn info ${FBREPO} | grep 'Repository UUID:' | cut -f3 -d' '` # Determine information about the local repositories. This supports more than # one "local" repository as long as they share the same UUID and the remote # repository used to commit is the same. ndx=0 for arg in "${@:-.}" do ((ndx++)) ARGS[${ndx}]=${arg} # Get argument info and compare the repo UUID against the primary UUID # since they need to be the same. svninfo=`svn info ${arg}` if [ `echo ${svninfo} | grep 'Repository UUID:' | cut -f3 -d' '` != \ ${FBREPOUUID} ] then fi LOCALURL[${ndx}]=`echo ${svninfo} | grep 'URL:' | cut -f2 -d' '` LOCALREPO[${ndx}]=`echo ${svninfo} | grep 'Repository Root:' | \ cut -f3 -d' '` LOCALSUFFIX[${ndx}]=`echo ${LOCALURL[${ndx}]} | \ sed -e "s|${LOCALREPO[${ndx}]}||"` FBURL[${ndx}]=${FBREPO}${LOCALSUFFIX[${ndx}]} # Exit if any repo is already pointing to the primary repo. if [ "${LOCALREPO[${ndx}]}" = "${FBREPO}" ] then echo "Switch ${arg} to a local repo before proceeding." exit fi done # Switch local repo(s) to primary repo. trap cleanup EXIT for ((ndx=1; ndx <= ${#ARGS}; ndx++)) do switch_repo_root ${ndx} 0 done # Commit. echo "Updating ${@} prior to commit." svn update "${@}" echo "Committing ${@}." svn commit "${@}" # Update local repo. if [ ${?} -eq 0 ] then echo "Syncing local repo." svnsync --non-interactive sync ${LOCALREPO[1]} fi