I write this post because I didn’t find perfect match to our svn exporting needs. Eventually performs an svn export only on changed files. Time to tome the php frameworks grows bigger and bigger – I had an unfortunate question here – well if I would like to use these nice frameworks and I don’t want to give up using subversion, the full export to the production environment is no longer acceptable.
The happy case trial ended like these:
$ svn export -r 80:81 https://svn.example.com/trunk/ ./testdiff svn: Revision range is not allowed
Finally I google a while and I made a bash script can handle incremental export. The methodology is quite simple:
#!/bin/bash
##############################
# settings and inicilization #
##############################
SVN_SOURCE="https://svn.example.com/trunk/"
REV_PATH="/var/www/revisions/example.com/"
PATCH_PATH="/var/www/patch/example.com/"
SYM_PATH="/var/www/public/example.com"
TIME_SPENT=$(date +%s)
REV=$(svn info $SVN_SOURCE | grep Revision | cut -d ' ' -f 2)
PREV=0
VERBOSIVE=0
USAGE_INFO="$(basename "$0") [-r REVISION_NUM] [-i PREVIOUS_REVISION_NUM] -- make an incremental svn export
where:
-i previous revision (default: 0)
-h show this help text
-r revision to export (default: $REV)
-v verbosive mode. show fetched files
current settins:
SVN_SOURCE: $SVN_SOURCE
REV_PATH: $REV_PATH
PATCH_PATH: $PATCH_PATH
SYM_PATH: $SYM_PATH
"
while getopts r:i:hv option; do
case "$option" in
i) PREV=$OPTARG
;;
h) echo "$USAGE_INFO"
exit
;;
r) REV=$OPTARG
;;
v) VERBOSIVE=1
;;
esac
done
EV_PATH=$REV_PATH$REV"/"
##############################
# functions #
##############################
promtYesOrDie(){
while true; do
read -e -p "$1 (y/n): " -i "y" yn
case $yn in
[Yy] ) break;;
[Nn] ) echo "spent: "$((`date +%s` - $TIME_SPENT))"s"
echo "bye bye"
exit
;;
* ) echo "Please answer (y)es or (n)o.";;
esac
done
}
doIncrementalExport(){
PREV_PATH=$REV_PATH$PREV"/"
if [ -d $PREV_PATH ]; then
echo "copying files from: $PREV_PATH"
cp -f -r "$PREV_PATH." $EV_PATH
echo "fetching added and modified files since revision $PREV..."
for FILE_SRC in $(svn diff --summarize -r $PREV:$REV $SVN_SOURCE | awk '/[AM]/ {print $2}'); do
FILE_PATH=$(echo $FILE_SRC | sed -e "s{$SVN_SOURCE{{");
if [ ! -d "$EV_PATH$FILE_PATH" ]; then
TRG_DIR="$EV_PATH$(dirname $FILE_PATH)"
mkdir -p $TRG_DIR
svn export -r$REV -q --force $FILE_SRC "$EV_PATH$FILE_PATH"
if [ $VERBOSIVE -eq 1 ]; then
echo "$EV_PATH$FILE_PATH"
fi
fi
done
echo "removing deleted files and folders since revision $PREV ..."
for FILE_SRC in $(svn diff --summarize -r $PREV:$REV $SVN_SOURCE | awk '/D/ {print $2}'); do
FILE_PATH=$(echo $FILE_SRC | sed -e "s{$SVN_SOURCE{{");
rm -r "$EV_PATH$FILE_PATH"
if [ $VERBOSIVE -eq 1 ]; then
echo "$EV_PATH$FILE_PATH"
fi
done
else
echo "previous revision does not exist at: $PREV_PATH"
exit;
fi
}
##############################
# main function #
##############################
if [ $PREV -eq 0 ]; then
promtYesOrDie "Do you want to do full export instead of incremental, for revision $REV of repo: [$SVN_SOURCE]"
echo "fatching source ..."
if [ $VERBOSIVE -eq 1 ]; then
svn export -r$REV --force $SVN_SOURCE $EV_PATH
else
svn export -r$REV -q --force $SVN_SOURCE $EV_PATH
fi
else
promtYesOrDie "Do you want to do incremental export, for revision renge $PREV:$REV of repo: [$SVN_SOURCE]"
doIncrementalExport
fi
echo "patching from $PATCH_PATH .."
cp -f -r "$PATCH_PATH." $EV_PATH
echo "changing owners and permissions .."
chown www-data:www-data -R $EV_PATH
chmod 0775 -R $EV_PATH
promtYesOrDie "Do you want to make the changes to do live? You should do it manually if got any error!"
echo "update symlink $SYM_PATH to $EV_PATH"
ln -sfn $EV_PATH $SYM_PATH
promtYesOrDie "Do you want to restart web server?"
echo "restarting php-fastcgi and nginx"
/etc/init.d/php-fastcgi restart
/etc/init.d/nginx restart
#echo "restarting apache"
#/etc/init.d/apache2 restart
echo "spent: "$((`date +%s` - $TIME_SPENT))"s"
echo [done]