Update svn checkout to specific date including externals
I want to perform an svn update to a specific date, and I can do this with svn update -r {2010-10-17}
. Unfortunately when this encounters an external it will do the update within the external without passing through the -r {2010-10-17}
option. This results in us getting the correct past revision of the base code, but the latest (undesired) versions of many of the externals.
How can I update to a specific revision or date and have this re开发者_JAVA百科curse correctly through the externals?
(Note: I understand that the mistake here might have been to use externals with no explicit revisions specified.)
I hope, anybody will implement my common-sense logic (limited to directory-type externals in some areas) into bash and cmd-script sooner or later and we'll get "definitive answer" to this repeating question
Your base task is:
svn up
your super-repo to needed point in past (updating to date /and without time/ is, BTW, not a best choice, but - apllicable)- get list of paths to all externals in your project (because externals definitions can exist anywhere in tree), from WC-root
svn propget svn:externals -R
(-R in order to check the whole tree without a lot ofcd
) - for each string in propget output (with format like this
. - https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib lib
): cd to the last field of string /relative to the first field, which is, in turn, is relative path to root/ and svn up to the same point, as it was done for superrepo:svn update -r {2010-10-17}
As result you'll have Mixed Working Copy, but superrepo and externals will be in state "for some revision in the past"
Note:
Additional sample for constructing local path to directory with externals (nested WC really) on more complex case.
For
>svn propget svn:externals -R
tags\1.0.1 - -r 2 https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib@2 lib
trunk - https://subversion.assembla.com/svn/subversion-trouble-shooting/trunk/lib lib
finals paths to externals in my WC will be (relative to WC-root)
tags\1.0.1\lib
trunk\lib
I'm adding this answer in case anyone's trying to update an already-checked-out subversion repository to sync the local file dates to the repo dates, which I wanted to do so I could do FS timestamp comparisons.
I made this oneliner to do the trick (but read the line below before using it):
svn info --show-item last-changed-date -R | xargs -I{} -P1000 -n1 sh -c 'x="{}"; set -x; exec touch -d "${x%% *}" "${x#* }"'
NOTE: The -P1000
specifies that xargs
should run 1000 simultaneous copies of sh
and touch
to do the actual updating. Depending on system load it may be wise to lower this. On a tiny i3-based Intel NUC 1000 processes actually turned out to be perfect, using 80-95% CPU (100% generally means the CPU is overloaded). If in doubt, open eg htop
and test with different values - but only run it for a few seconds, because it will need to run from the start each time.
For a small ~3GB SVN repo on a USB HDD, this took about 5 minutes to run.
The set +x
turns on verbose execution, which I do just before executing touch
so you can watch it run. If you want non-verbose execution, remove that command.
We include only whole dirs in other projects:
- mainprj/bin/subprj1
- mainprj/bin/subprj2
- mainprj/dat/subprj1
- mainprj/dat/subprj2
- subprj1/bin # included in mainprj/bin/subprj1
- subprj1/dat # included in mainprj/dat/subprj1
- subprj2/bin # included in mainprj/bin/subprj2
- subprj2/dat # included in mainprj/dat/subprj2
with this layout svn propget svn:externals -R
returns
# cd mainprj
# svn propget svn:externals -R
bin - subprj1 svn+ssh://svnserver/svn/subprj1/trunk/bin
subprj2 svn+ssh://svnserver/svn/subprj2/trunk/bin
dat - subprj1 svn+ssh://svnserver/svn/subprj1/trunk/dat
subprj2 svn+ssh://svnserver/svn/subprj2/trunk/dat
and you can update to a fix date as follows:
svn propget svn:externals -R |\
grep -vE '^$' | sed -e "s/^[^-]* - //" |\
while read line; do \
pushd ${line##*/}; \
svn update -r {2019-04-26} ${line%% *}; \
popd; \
done
As far as I've been able to work out, you can't do this without changing your externals config. But, changing the externals config changes it for everyone, so it's just a single commit and update and you're done.
精彩评论