I\'m working on a large, established project under SVN control. Many parts of the code base are being checked out as externals, but are being actively worked on by other peo
Let svn do the recursion for you.
The tempfile and tee
are only here so that you can see the full output:
SVN_UP_OUTPUT=$(mktemp SVN_UP_OUTPUT.XXXXX)
svn up -r$REVISION | tee $SVN_UP_OUTPUT
cat $SVN_UP_OUTPUT | egrep '^Fetching external' | egrep -o "'.*'" | sed -e "s/'//g" | while read DIR;do
echo $$ svn up -r$REVISION "$DIR"
svn up -r$REVISION "$DIR"
done
rm $SVN_UP_OUTPUT
If you don't care about the output, it can be shortened to this:
svn up -r$REVISION | egrep '^Fetching external' | egrep -o "'.*'" | sed -e "s/'//g" | while read DIR;do
svn up -r$REVISION "$DIR"
done
And of course, in your case:
REVISION='{20090324}'
When using svn:externals, it is generally a bad idea to use an external without a revision number. It means that it becomes hard to correlate the version of the external with the version of the containing project; I know this the hard way, from trying to track down some history in a project that contained externals, and I would have to guess which revision corresponded to the revision in the containing project (sometimes it was earlier because someone had updated the external project and then updated the containing project, sometimes it was later because someone had edited files directly in the external checkout and then committed it).
Instead, as suggested by the tip box a couple paragraphs into the externals section in the subversion book, you should always commit externals with a revision number. That way, whenever you check out a particular revision of the containing project, the appropriate revision of the external will also be checked out. It does mean a little more work, as you have to update the revision number in the svn:externals property every time (we wrote a script to do it automatically), but in the long run it is a much better solution.
edit: Here is the skeleton of the script we used (a rake task) for conveniently updating the external and keeping everything in sync.
desc 'Update external for this project (rake update_external r=17789)'
task :update_external do |t|
rev = ENV['r']
rev =~ /^\d+$/ or raise "Invalid SVN revision number: r=<#{rev}>"
# Update the project.
sh "svn update"
URL = 'svn+ssh://example.com/external/trunk'
sh "svn propset svn:externals 'external -r#{rev} #{URL}' containing/directory"
# Update again -- to put the externals back to the right revision.
sh "svn update"
end
nice utility that will freeze externals given a path. we use this util to freeze externals after we create a tag from the trunk:
http://svnxf.codeplex.com/
KSvn might have this feature. http://subversion.tigris.org/links.html#desktop-integrations
As I have recently had a similar problem, I wrote a little script to checkout a repository at a specific revision while also checking out the externals at the date of that revision: https://gist.github.com/3413952
Useful if you need to find the source of a bug and want to have something similar to git
's bisect feature.
Based on Dave Cohen's answer, but quite a bit faster:
find . -name '.svn' -execdir svn up --ignore-externals -r '{2014-02-05}' \;