You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@subversion.apache.org by Craig Peterein <cr...@peterein.org> on 2002/12/06 01:27:39 UTC

cadaver+expect+wget = svn co

Someone a while back wanted to wget from an svn repository.  But you can't just
grab the regular url, since someone may commit in the middle.  I wrote the
script below as a small exercise, and as an excuse to install cadaver.  Given a
repository and a path, it gets the baseline collection url.

Props to sussman for walking me through the three steps to the baseline
collection.  That was a few weeks ago on irc.

Enjoy :-)

Craig

$ cat get-bc-url
#!/usr/bin/env expect

log_user 0
set timeout -1
set usage_text "
Returns the current magic baseline collection URL for a given REPO PATH
combination.  If authentication is required, use USER and read the password
from stdin.

Usage:
get-bc-url REPO PATH \[USER]

Examples:
get-bc-url http://svn.collab.net/repos/svn trunk

get-bc-url http://host/repo path user << EOF
password
EOF

bcurl=\$(get-bc-url ...)
wget -q -np --mirror -e \"robots = off\" \"\${bcurl}\"
"

proc usage {} {
	global usage_text
	send_error "$usage_text"
	exit
}

if { $argc < 2 } { usage }

set url [string trim [lindex "$argv" 0] "/"]
set path [string trim [lindex "$argv" 1] "/"]
set username [lindex "$argv" 2]

proc handle_auth {} {
	global username
	if { $username == "" } { usage }

	send "$username\n"

	expect "Password:"
	stty -echo
	expect_user -re "(.*)\n"
	stty echo
	set password "$expect_out(1,string)"

	send "$password\n"
	expect ">"
}

spawn cadaver $url
expect ">" {} "Username:" { handle_auth }

send "set namespace DAV:\n"
expect ">"

# figure out version controlled configuration
send "propget . version-controlled-configuration\n"
expect -re "<href>(.+)</href>"
set vcc "$expect_out(1,string)"
expect ">"

# figure out baseline resource
send "propget $vcc checked-in\n"
expect -re "<href>(.+)</href>"
set br "$expect_out(1,string)"
expect ">"

# figure out baseline collection
send "propget $br baseline-collection\n"
expect -re "<href>(.+)</href>"
set bc "$expect_out(1,string)"
expect ">"

send "cd $bc$path\n"
expect ">"

send "pwd\n"
expect -re "`(.+)'\."
set out "$expect_out(1,string)"

send_user "$out\n"


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: cadaver+expect+wget = svn co

Posted by Ben Collins-Sussman <su...@collab.net>.
"Craig Peterein" <cr...@peterein.org> writes:

> Someone a while back wanted to wget from an svn repository.  But you
> can't just grab the regular url, since someone may commit in the
> middle.

Sorry, I totally misunderstood what your script is doing.  When you
talked about 'wget a url' above, I thought you were talking about a
single GET on some public file url.  But you're actually talking about
making wget retrieve an entire tree!

Yes, if you try to walk a the "public tree" of urls, then the tree may
change between GETs and PROPFINDs.  So your script is all good... it
gets a baseline-collection url (via cadaver) which represents a
*single* immutable revision tree, and then uses 'wget' to magically
walk the tree.

Never mind.  :-)


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org

Re: cadaver+expect+wget = svn co

Posted by Ben Collins-Sussman <su...@collab.net>.
"Craig Peterein" <cr...@peterein.org> writes:

> Someone a while back wanted to wget from an svn repository.  But you
> can't just grab the regular url, since someone may commit in the
> middle. 

It's very cool that you wrote this script!  It's nice to be able to
get an arbitrary revision of a file using wget.  You should add a
"revnum" argument to the script.

But your explanation above isn't quite right.

If I do a GET on a public url, mod_dav_svn immediately figures out the
youngest revision, and then sends back the text of the file at that
particular revision.  If somebody commits a new revision during the
data transfer, it doesn't mean a thing.  You still finish fetching a
particular (rev, path) coordinate pair from the repository.

The only "race" condition here is the race between mod_dav_svn doing a
single db lookup of the HEAD revnum, and somebody committing a new
HEAD.  Once mod_dav_svn has a specific revnum, it stays with it.


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org