I recently posted a Subversion Command Line Script to export changed files and in response to a comment on that page have posted a new version here, which writes out the current revision number to a file and only exports from that revision when the script is run again.
The BASH script
As with my previous post, I’m not really going to bother explaining how the script works; there’s some inline comments and if you don’t understand shell scripting or using SVN from the command line then this probably isn’t for you anyway 🙂
Just one quick note: the script writes out the current revision number to a file at the export directory called .revision If you want to call it something else or store it somewhere else then modify the script to suit.
#!/bin/bash if [ ! $1 ] || [ ! $2 ]; then echo "Please enter an SVN repository, target directory and optionally a revision from" exit fi # set up nice names for the incoming parameters to make the script more readable repository=$1 target_directory=$2 revision_from=$3 # if revision_from is not already set, get it from the .revision file if it exists if [ ! $revision_from ] && [ -f $target_directory/.revision ]; then revision_from=`cat $target_directory/.revision` fi # now either get it from a specific revision, or everything if [ $revision_from ]; then # the grep is needed so we only get added/modified files and not the deleted ones or anything else # if it's a modified directory it's " M" so won't show with this command (good) # if it's an added directory it's still "A" so will show with this command (not so good) for line in `svn diff --summarize -r$revision_from:HEAD $repository | grep "^[AM]"` do # each line in the above command in the for loop is split into two: # 1) the status line (containing A, M, AM, D etc) # 2) the full repository and filename string # so only export the file when it's not the status line if [ $line != "A" ] && [ $line != "AM" ] && [ $line != "M" ]; then # use sed to remove the repository from the full repo and filename filename=`echo "$line" |sed "s|$repository||g"` # don't export if it's a directory we've already created if [ ! -d $target_directory$filename ]; then directory=`dirname $filename` mkdir -p $target_directory$directory svn export $line $target_directory$filename fi fi done # to summarize any deleted files or directories at the end of the script uncomment the following line #svn diff --summarize -r$revision_from:HEAD $repository | grep "^[D]" else svn export --force $repository $target_directory fi # get the current revision and write to .revision file echo `svn info $repository | grep ^Revision | sed 's/Revision: *//'` > $target_directory/.revision
Save the above script as a file and change the permissions so it’s executable. Then run it like so, where I’ve saved it as svn-export:
./svn-export repository target-directory [optionally revision-from]
where repository and target-directory are the full URL to the SVN repository and local target directory to export the files to. There is a 3rd optional parameter to explicitly set a revision from which will override whatever is in the .revision file.
For example, to export changes from the repository svn://localhost/myrepository to /my/path do this:
./svn-export svn://localhost/myrepository /my/path
If the directory /my/path does not exist or the .revision file does not exist, the whole current HEAD will be exported. When .revision does exist it will export from the revision number it was the last time the command was run.
Note that the script does not delete files or directories. Uncomment the line under "# to summarize any deleted files or directories at the end of the script uncomment the following line" to show the files and directories that have been deleted between revisions.