Sander Striker wrote:
>>From: Ross Mark [mailto:rossm@controllingedge.com.au]
>>Sent: Tuesday, August 12, 2003 12:53 AM
>>
>>
>>Well there is but it takes a small wrapper script around svn to save the
>>symlink as a property of the directory plus add it to the ignore file. I
>>use subversion for maintaining entire filesystems so my wrapper takes
>>care of symlinks, devices plus ownership and permissions. If updates
>>only set the modification time on the file to what was in the repository
>>I would be very happy.
>>
>>
>
>Would you be willing to include that script in contrib/ ?
>
>Sander
>
>
>
Sure I would be happy to share it around. All I know is that it works on
mine and a few other machines from RH7.2 to 8.0 so there may be some
portability issues. Plus I don't know how it will handle different
filenames ie spaces and extended character sets. It also assumes that
every file and directory is under version control..
I've attached it to this email. I called it asvn for Archive SVN. Seemed
good at the time. It is run as a direct replacement for svn. The only
mistake I have made is that I didn't choose a very good name space for
the properties that I used but since I already have a number of
repositories that are using it I can't be bothered to change them.
Hope someone gets some use from this.
Ross
#!/bin/bash
#-------------------------------------------------------------------------
# Author: Ross Mark (rossm@controllingedge.com.au)
# Date: Tue Mar 11 10:02:57 EST 2003
#
# Document Id: 104.733.737
#
# Copyright (C) 2003 Controlling Edge Pty Ltd
#
#-------------------------------------------------------------------------
#
# Description:
# Archive SVN (asvn) will allow the recording of file types not
# normally handled by svn. Currently this includes devices,
# symlinks and file ownership/permissions.
#
# Every file and directory has a 'file:permissions' property set and
# every directory has a 'dir:devices' and 'dir:symlinks' for
# recording the extra information.
#
# Run this script instead of svn with the normal svn arguments.
#
# This script worked for me yesterday on my machine and I hope it will
# continue to work tomorrow. If you run this program then
# risk and blame are yours.
#
#-------------------------------------------------------------------------
SVN=/usr/local/bin/svn
ACTION=""
DEV_PROP="dir:devices"
SYM_PROP="dir:symlinks"
FILE_PROP="file:permissions"
TMPFILE=/tmp/asvn.tmp.$$
TMPFILE1=/tmp/asvn.tmp1.$$
TMPFILE2=/tmp/asvn.tmp2.$$
PCWD=`/bin/pwd`
SKIPSVN='\( -name .svn -prune -false \)'
PRINTDETAILS="-printf \"file='%p' mode=%m user=%u(%U) group=%g(%G)\n\""
trap cleanup 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
function cleanup()
{
rm -f $TMPFILE $TMPFILE1 $TMPFILE2
}
function basedirname()
{
refname="$1"
dir="`dirname $2`"
ref=`expr "$dir" : "$refname/\(.*\)"`
if [ -z "$ref" ]
then
echo .
else
echo $ref
fi
}
#
# Modifies TMPFILE2
#
function addignorefile()
{
file=`basename $1`
dir=`dirname $1`
efile="`echo $file |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`"
gefile="`echo $efile |sed -e 's!\(\\\\\)!\\\\\\\\\1!g'`"
if ! ($SVN propget svn:ignore "$dir" | grep -q "^$gefile\$")
then
$SVN propget svn:ignore "$dir" |sed -e '/^$/d' >$TMPFILE2
echo "$efile" >>$TMPFILE2
$SVN propset svn:ignore -F $TMPFILE2 "$dir"
echo setting ignore
#cat $TMPFILE2 >&2
fi
}
function deleteignorefile()
{
file=`basename $1`
dir=`dirname $1`
efile="`echo $file |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`"
gefile="`echo $efile |sed -e 's!\(\\\\\)!\\\\\\\\\1!g'`"
echo "deleting ignore setting for '$file'"
if ($SVN propget svn:ignore "$dir" | grep -q "^$gefile\$")
then
$SVN propget svn:ignore "$dir" |sed -e '/^$/d' |grep -v "^$gefile\$" >$TMPFILE2
$SVN propset svn:ignore -F $TMPFILE2 "$dir"
#cat $TMPFILE2 >&2
fi
}
function recorddirinfo
{
eval "find $PCWD $SKIPSVN -o \( -type d ! -name .svn -print \)" |while read dirlist
do
updatedirsymlinks $1 $dirlist
updatedirdevices $1 $dirlist
done
}
function updatedirdevices()
{
CHECKIN=false
if [ "$1" = "-ci" ]
then
CHECKIN=true
shift
fi
dir="$1"
echo checking $dir for devices
#
# Obtain the list of devices in this directory
#
find "$dir" \( \( -type b -o -type c -o -type p \) -print \) -o -type d ! -name "`basename $dir`" -prune | while read file
do
echo -n `find $file -printf "file='%f' mode=%m user=%u(%U) group=%g(%G)"`
[ -b $file ] && echo -n ' type=b'
[ -c $file ] && echo -n ' type=c'
[ -p $file ] && echo ' type=p'
if [ -b $file -o -c $file ]
then
ls -l $file |
sed -e 's/^[-lcpbrdwxXstugoTS]* *[0-9] [^ ]* *[^ ]* *\([0-9]*\), *\([0-9]*\) .*/ major=\1 minor=\2/'
fi
# In this case file is the full path.
addignorefile "$file"
done | sort >$TMPFILE
#
# Obtain the currently defined devices
#
$SVN propget $DEV_PROP $dir >$TMPFILE1
#
# If the two list are the same then there is nothing to do.
#
if /usr/bin/cmp $TMPFILE1 $TMPFILE >/dev/null
then
return
fi
if [ -s $TMPFILE ]
then
# There are devices in this directory
if [ "$CHECKIN" = "true" ]
then
# Add the current devices to the property
$SVN propset $DEV_PROP $dir -F $TMPFILE
else
# Delete all the unwanted devices ie not in TMPFILE1
cat $TMPFILE |while read line
do
file=`expr "$line" : "file='\(.*\)' mode"`
if ! grep -q "file='$file'" $TMPFILE1
then
rm $file
deleteignorefile $file
fi
done
fi
else
# There are no devices in this directory
if [ "$CHECKIN" = "true" ]
then
$SVN propdel $DEV_PROP $dir
fi
fi
#
# If we are not a checkin then make sure all the devices are defined
#
if [ "$CHECKIN" != "true" ]
then
cat $TMPFILE1 |while read info
do
#echo info = $info
[ -z "$info" ] && continue
grep -q "$info" $TMPFILE && continue # This line still matches
file=`expr "$info" : "file='\(.*\)' "`
mode=`expr "$info" : ".*' mode=\([0-9]*\) "`
user=`expr "$info" : ".* user=\([^(]*\)("`
uid=`expr "$info" : ".* user=[^(]*(\([0-9]*\) "`
group=`expr "$info" : ".* group=\([^(]*\)("`
gid=`expr "$info" : ".* group=[^(]*(\([0-9]*\) "`
type=`expr "$info" : ".* type=\(.\)"`
major=`expr "$info" : ".* major=\([0-9]*\)"`
minor=`expr "$info" : ".* minor=\([0-9]*\)"`
#
# This file is either missing or wrong
# Delete the old and create it anew.
#
rm -f $dir/$file
mknod --mode=$mode $dir/$file $type $major $minor
chown $user:$group $dir/$file
addignorefile $dir/$file
done
fi
}
function updatedirsymlinks()
{
CHECKIN=false
if [ "$1" = "-ci" ]
then
CHECKIN=true
shift
fi
dir="$1"
echo checking $dir for symlinks
cp /dev/null $TMPFILE
#
# Obtain the list of symlinks in this directory
#
find "$dir" \( -type l -printf "file='%f' dest='%l'\n" \) -o -type d ! -name "`basename $dir`" -prune |
sort >$TMPFILE
#
# Make sure all the symlinks are being ignored.
#
cat $TMPFILE |while read line
do
file=`expr "$line" : "file='\(.*\)' dest"`
addignorefile "$dir/$file"
done
#
# Obtain the currently defined symlinks
#
$SVN propget $SYM_PROP $dir >$TMPFILE1
#
# If the two list are the same then there is nothing to do.
#
if cmp $TMPFILE1 $TMPFILE >/dev/null
then
return
fi
if [ -s $TMPFILE ]
then
# There are symlinks in this directory
if [ "$CHECKIN" = "true" ]
then
# Add the current symlinks to the property
$SVN propset $SYM_PROP $dir -F $TMPFILE
else
# Delete all the unwanted symlinks
cat $TMPFILE |while read line
do
file=`expr "$line" : "file='\(.*\)' dest"`
efile="`echo $file |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`"
if ! grep -q "file='$efile'" $TMPFILE1
then
rm $dir/$file
deleteignorefile $dir/$file
fi
done
fi
else
# There are no symlinks in this directory
if [ "$CHECKIN" = "true" ]
then
$SVN propdel $SYM_PROP $dir
fi
fi
#
# If we are not a checkin then make sure all the symlinks are defined
#
if [ "$CHECKIN" != "true" ]
then
cat $TMPFILE1 |while read info
do
[ -z "$info" ] && continue
file=`expr "$info" : "file='\(.*\)' dest"`
dest=`expr "$info" : ".*' dest='\(.*\)'$"`
if [ -L $dir/$file ]
then
[ "`find $dir/$file -printf '%l'`" = "$dest" ] && continue
fi
rm -f $dir/$file
ln -s $dest $dir/$file
done
fi
}
function recordpermissions()
{
CHECKIN=false
if [ "$1" = "-ci" ]
then
CHECKIN=true
shift
fi
# Find all the directories and files
cp /dev/null $TMPFILE
eval "find $PCWD $SKIPSVN -o \( \( -type d ! -name .svn \) -o -type f \) $PRINTDETAILS" | while read info
do
device=`expr "$info" : "file='\(.*\)' mode"`
info=`expr "$info" : "file='.*' \(mode.*\)"`
if [ "$PCWD" = "$device" ]
then
dir="."
file=""
else
dir="`basedirname $PCWD $device`"
file="`basename $device`"
fi
# see if the properties have changed.
if [ "`$SVN propget $FILE_PROP $dir/$file`" != "$info" ]
then
if [ "$CHECKIN" = "true" ]
then
$SVN propset $FILE_PROP "$info" $dir/$file
else
info=`$SVN propget $FILE_PROP "$dir/$file"`
mode=`expr "$info" : "mode=\([0-9]*\) "`
user=`expr "$info" : ".* user=\([^(]*\)("`
uid=`expr "$info" : ".* user=[^(]*(\([0-9]*\) "`
group=`expr "$info" : ".* group=\([^(]*\)("`
gid=`expr "$info" : ".* group=[^(]*(\([0-9]*\) "`
chown $user:$group $dir/$file
chmod $mode $dir/$file
fi
fi
done
}
function pre_checkin()
{
echo this is the pre checkin process
recorddirinfo -ci
recordpermissions -ci
}
function post_checkout()
{
echo this is the post checkout process
if [ "$CHDIR" = "true" ]
then
shift $(($# -1))
cd $1
PCWD="$PCWD/$1"
fi
recorddirinfo
recordpermissions
}
CHDIR=false
case "$1" in
checkout|co) CHDIR=true; ACTION="post";;
commit|ci) ACTION="pre";;
switch|sw) ACTION="post";;
update|up) ACTION="post";;
*);;
esac
[ "$ACTION" = "pre" ] && pre_checkin $@
$SVN $@
[ $? = 0 -a "$ACTION" = "post" ] && post_checkout $@
cleanup
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@subversion.tigris.org
For additional commands, e-mail: users-help@subversion.tigris.org
Received on Tue Aug 12 03:11:03 2003