atom feed4 messages in org.tigris.subversion.dev[PATCH] new patch for asvn script
FromSent OnAttachments
Scott MillerOct 30, 2006 8:35 am.txt
Peter SamuelsonOct 30, 2006 3:51 pm 
Scott MillerOct 31, 2006 11:28 am 
Erik HuelsmannOct 31, 2006 11:29 am 
Subject:[PATCH] new patch for asvn script
From:Scott Miller (Scot@prioritytech.com)
Date:Oct 30, 2006 8:35:16 am
List:org.tigris.subversion.dev
Attachments:

After having an off list discussion with Bisho, and then discovering the filename quoting problems, I've extensively reworked the asvn script. I've still got several things to fix, but I really need to work on checking stuff in, so I'm submitting this patch set for now. Expect further fixes in a month or so.

Things that this script does: o Commented out the code dealing with symbolic links since subversion now has that capability built in.

o Eliminated the need to traverse the directory tree more than once. It now does a single pass, checking each file for device type and Then file permissions.

o Modified some of the 'find' calls as needed to eliminate processing entire subdirectory trees that are not under subversion control.

o Filenames with "characters that need to be quoted" should now work.

o I've added an option "prework", or "pre" for short, that makes this script do its work without calling the svn executable when it is done.

o Unlike the previous patch, this one does not attempt to fix the indentation issues.

Things that still need to be fixed: o Devices are saved with absolute paths rather than relative paths, so creating a new working directory will not also recreate the devices correctly. (They won't be created at all, the resulting name is completely incorrect)

o asvn does not take into account the fact that svn can work on remote directories (ie, not your present working directory). asvn only works if executed from within an svn working directory.

-Scott L. Miller Senior Network Engineer Priority Technologies, Inc.

--- asvn.org 2006-10-16 11:24:15.000000000 -0500 +++ new-asvn 2006-10-30 09:48:53.000000000 -0600 @@ -34,6 +34,26 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +#------------------------------------------------------------------------- +# +# Modified 10/12/2006 by Scott L. Miller (scot@gmail.com) +# +# Commented out the code dealing with symbolic links since subversion +# now has that capability built in. +# +# Eliminated the need to traverse the directory tree more than once. +# It now does a single pass, checking each file for device type and +# file permissions. +# +# Modified some of the 'find' calls as needed to eliminate processing +# entire subdirectory trees that are not under subversion control. +# +# Changed indentation to follow a consistent style. +# +# FURTHER THOUGHTS, AND SUGGESTIONS: Use a subversion status call +# to directly collect the files that we need to process for device +# and permission properties, rather than recursing through the +# directory tree ourselves. # #------------------------------------------------------------------------- SVN=/usr/local/bin/svn @@ -58,7 +78,7 @@ function basedirname() { refname="$1" - dir="`dirname $2`" + dir="`dirname \"$2\"`" ref=`expr "$dir" : "$refname/\(.*\)"` if [ -z "$ref" ] then @@ -69,46 +89,59 @@ }

# +# Escapes all "special" filename characters. SED magic was modified from +# the original found at the website: +# http://elonen.iki.fi/code/misc-notes/remove-duplicate-files/index.html +# +function escapename() +{ + echo "`echo $1 | sed -r 's/([^a-zA-Z0-9./_-])/\\\\\1/g'`" +} + +# # Modifies TMPFILE2 # function addignorefile() { - file=`basename $1` - dir=`dirname $1` + file=`basename "$1"` + dir=`dirname "$1"`

- efile="`echo $file |sed -e 's!\([\[\(\$]\)!\\\\\1!g'`" - gefile="`echo $efile |sed -e 's!\(\\\\\)!\\\\\\\\\1!g'`" + efile="`escapename \"$file\"`" + gefile="`echo $efile |sed -e 's!\([\\]\)!\1\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 + $SVN propset svn:ignore -F $TMPFILE2 "$dir" > /dev/null 2>&1 + # 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'`" + file=`basename "$1"` + dir=`dirname "$1"` + + efile="`escapename \"$file\"`" + gefile="`echo $efile |sed -e 's!\([\\]\)!\1\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" + $SVN propset svn:ignore -F $TMPFILE2 "$dir" > /dev/null 2>&1 #cat $TMPFILE2 >&2 fi }

function recorddirinfo { - eval "find $PCWD $SKIPSVN -o \( -type d ! -name .svn -print \)" |while
read dirlist + find "$PCWD" \( -type d -name .svn -print \) | sed -e 's/\/\.svn//' | while
read dirlist do - updatedirsymlinks $1 $dirlist - updatedirdevices $1 $dirlist +# updatedirsymlinks $1 $dirlist + updatedirdevices $1 "$dirlist" + recordpermissions $1 "$dirlist" done }

@@ -126,15 +159,17 @@ # # 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 + find "$dir" -maxdepth 1 \( -type b -o -type c -o -type p \) -printf "file='%p'
mode=%m user=%u(%U) group=%g(%G)\n" | + sed -r 's#\\#\\\\#g' | sort | while read devinfo 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 ] + file=`expr "$devinfo" : "file='\(.*\)' mode"` + echo -n "$devinfo" + [ -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 | + 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. @@ -145,10 +180,10 @@ # # Obtain the currently defined devices # - $SVN propget $DEV_PROP $dir >$TMPFILE1 + $SVN propget $DEV_PROP "$dir" >$TMPFILE1

# - # If the two list are the same then there is nothing to do. + # If the two lists are the same then there is nothing to do. # if /usr/bin/cmp $TMPFILE1 $TMPFILE >/dev/null then @@ -161,7 +196,7 @@ if [ "$CHECKIN" = "true" ] then # Add the current devices to the property - $SVN propset $DEV_PROP $dir -F $TMPFILE + $SVN propset $DEV_PROP "$dir" -F $TMPFILE else # Delete all the unwanted devices ie not in TMPFILE1 cat $TMPFILE |while read line @@ -169,8 +204,8 @@ file=`expr "$line" : "file='\(.*\)' mode"` if ! grep -q "file='$file'" $TMPFILE1 then - rm $file - deleteignorefile $file + rm "$file" + deleteignorefile "$file" fi done fi @@ -178,7 +213,7 @@ # There are no devices in this directory if [ "$CHECKIN" = "true" ] then - $SVN propdel $DEV_PROP $dir + $SVN propdel $DEV_PROP "$dir" fi fi

@@ -205,14 +240,15 @@ # 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 + rm -f "$dir/$file" + mknod --mode=$mode "$dir/$file" $type $major $minor + chown $user:$group "$dir/$file" + addignorefile "$dir/$file" done fi }

+# No longer needed. function updatedirsymlinks() { CHECKIN=false @@ -310,27 +346,44 @@ CHECKIN=true shift fi + dir="$1"

- # Find all the directories and files + echo checking $dir for permissions cp /dev/null $TMPFILE - eval "find $PCWD $SKIPSVN -o \( \( -type d ! -name .svn \) -o -type f \)
$PRINTDETAILS" | while read info + # + # Obtain the list of files and subdirectories in this directory + # We also need to fix the backslash characters before the 'while read' or + # they will get interepreted within the read. + # + find "$dir" -maxdepth 1 \( -type f -o \( -type d ! -name \.svn \) \) -printf
"file='%p' mode=%m user=%u(%U) group=%g(%G)\n" | + sed -r 's#\\#\\\\#g' | sort | while read info do - device=`expr "$info" : "file='\(.*\)' mode"` + file=`expr "$info" : "file='\(.*\)' mode"` info=`expr "$info" : "file='.*' \(mode.*\)"` - if [ "$PCWD" = "$device" ] + + if [ "$PCWD" = "$file" ] then dir="." file="" else - dir="`basedirname $PCWD $device`" - file="`basename $device`" + dir="`basedirname \"$PCWD\" \"$file\"`" + file="`basename \"$file\"`" + # All chars except spaces and tabs seem to be handled correctly + # within the double quotes, so we just fix the spaces and tabs + file="`echo \"$file\" | sed -r 's#\([\ \ ]\)#\\\\\1#g'`" fi + + props="`$SVN propget $FILE_PROP \"$dir/$file\"`" + if [ $? -eq 0 ] + then + #file is under svn control + # see if the properties have changed. - if [ "`$SVN propget $FILE_PROP $dir/$file`" != "$info" ] + if [ "$props" != "$info" ] then if [ "$CHECKIN" = "true" ] then - $SVN propset $FILE_PROP "$info" $dir/$file + $SVN propset $FILE_PROP "$info" "$dir/$file" else info=`$SVN propget $FILE_PROP "$dir/$file"` mode=`expr "$info" : "mode=\([0-9]*\) "` @@ -338,15 +391,24 @@ uid=`expr "$info" : ".* user=[^(]*(\([0-9]*\) "` group=`expr "$info" : ".* group=\([^(]*\)("` gid=`expr "$info" : ".* group=[^(]*(\([0-9]*\) "` + if [ "$user" = "" -o "$group" = "" -o "$mode" = "" ] then - echo "property $FILE_PROP not set for $dir/$file" + echo "property $FILE_PROP not set for \"$dir/$file\"" else - chown $user:$group $dir/$file - chmod $mode $dir/$file + echo "changing owner/group mode on \"$dir/$file\"" + chown $user:$group "$dir/$file" + chmod $mode "$dir/$file" fi fi fi + + else + #file is not under svn control + # echo -n "" is just a no-op allowing this else block to exist + echo -n "" + fi + done }

@@ -355,7 +417,8 @@ { echo this is the pre checkin process recorddirinfo -ci - recordpermissions -ci +# recordpermissions is called from recorddirinfo now +# recordpermissions -ci }

function post_checkout() @@ -368,13 +431,17 @@ PCWD="$PCWD/$1" fi recorddirinfo - recordpermissions +# recordpermissions is called from recorddirinfo now +# recordpermissions }

CHDIR=false +DOSVN=true case "$1" in checkout|co) CHDIR=true; ACTION="post";; commit|ci) ACTION="pre";; +import) ACTION="pre";; +prework|pre) DOSVN=false; ACTION="pre";; switch|sw) ACTION="post";; update|up) ACTION="post";; *);; @@ -382,11 +449,15 @@

[ "$ACTION" = "pre" ] && pre_checkin $@

-$SVN $@ +if [ "$DOSVN" = "true" ] +then + echo $SVN "$@" + $SVN "$@" +fi

[ $? = 0 -a "$ACTION" = "post" ] && post_checkout $@

cleanup # -# vim: set ai ts=8 sw=4 +# vim:ai:ts=4:sw=4 #