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
This is the best solution to the problem I found to date (it's a tricky problem - subversions devs should fix it in the core). This example deals with mplayer in particular but you should easily see the logic.
; fetch the rev I want without including the externals
svn checkout -r "$REV" --ignore-externals \
svn://svn.mplayerhq.hu/mplayer/trunk
; grab the date of that rev from the svn info output
DATE=`svn info trunk|sed -n '/^Last Changed Date/s/.*: \(.*\) (.*/\1/p'`
; fetch the externals using that date
svn checkout -r "{$DATE}" \
svn://svn.mplayerhq.hu/ffmpeg/trunk/libavutil \
svn://svn.mplayerhq.hu/ffmpeg/trunk/libavformat \
svn://svn.mplayerhq.hu/ffmpeg/trunk/libavcodec \
svn://svn.mplayerhq.hu/ffmpeg/trunk/libpostproc
This is tricky, and I'm afraid I can't offer a good solution to your current situation - but Brian has given the answer on how to avoid it.
The avoidance comes down to a little bit of repository theory - basically it must not be possible to modify any source code for your project without a corresponding revision appearing in trunk.
By pointing all externals to tags or specific revisions, no changes from them can appear in the main project history without committing a change to the external reference. But if you point an external to a moving trunk, a change to the external will not show up in the main project's timeline at all - leaving you in the position you're in.
Personally, I've taken the view that externals should be treated and released as independent projects, hence all externals point to tags. During heavy parallel development, it's fine to 'switch' an external to trunk, or to have an unstable development branch temporarily pointing to an external trunk, but the mainline project trunk always points to a stable external, and it's a conscious decision to upgrade. This view may be overkill for your situation, but it's worth seeing other possibilities.
The revision/date/etc you're updating the main WC to does not get passed through to the externals when they are being updated. In the absence of a specific revision specified in the externals definition, they will always track the head of whatever they point at. If you specify a revision there, then that's the only revision you'll ever get. I'm pretty sure what you're trying to do is impossible -- it's an approach I tried to use to solve a problem I was having, as I describe in this question. (I never did solve that problem, though I think the proxy idea that's mentioned there could do it. It probably won't help you though)
This is inefficient, in that it calls svn update more often than (usually) required. Otherwise, it is short an sweet:
Unix:
find . -name .svn -execdir svn update -r {2010-08-30} \;
Windows:
forfiles /m .svn /s /c "cmd /c svn up -r {2010-08-30}"
The problem here is that you and your colleagues have not been using explicit revision numbers with your externals. You should begin at once!
Intuitively I might have thought that checking out something from a specific date would recursively "peg" the externals look-up to that date, even where the externals point to some HEAD
revision. But, well, it doesn't.
I still haven't got a perfect solution, but this one comes close:
svn propget svn:externals | sed -e 's/ .*$//g' | xargs svn up -r'{20090324}'
This works in my case because there's no recursive externals, and all externals are defined with no spaces in the directory or a revision number, so the regular expression can easily chop off the trailing repository path.
I'm sure there's better regex that will solve the problem generically, though.
Edit: Actually the more I think about this, the more problems I see. The biggest of which is that it's using the svn:externals from the current version, rather than the svn:externals of the version at the specified date. This is even more complex than I first thought.