Mercurial > hg
diff hgext/convert/subversion.py @ 9829:1b2516a547d4
convert/svn: delegate to svn bindings if HTTP probe fails
convert extension tries to guess the remote repository type with HTTP probes.
Unfortunately, it does not handle authentication or HTTPS handshakes, so regular
svn repositories may be excluded. Instead, when a non-404 error is retrieved,
we keep trying with the svn bindings. The drawback is missing svn bindings will
make the conversion to fail even for non-svn targets. This can be avoided with
--source.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Wed, 11 Nov 2009 19:45:00 +0100 |
parents | dec177286deb |
children | 2e51cc30fc30 |
line wrap: on
line diff
--- a/hgext/convert/subversion.py Wed Nov 11 18:32:56 2009 +0100 +++ b/hgext/convert/subversion.py Wed Nov 11 19:45:00 2009 +0100 @@ -8,6 +8,7 @@ import cPickle as pickle import tempfile import urllib +import urllib2 from mercurial import strutil, util, encoding from mercurial.i18n import _ @@ -136,7 +137,7 @@ # Check to see if the given path is a local Subversion repo. Verify this by # looking for several svn-specific files and directories in the given # directory. -def filecheck(path, proto): +def filecheck(ui, path, proto): for x in ('locks', 'hooks', 'format', 'db', ): if not os.path.exists(os.path.join(path, x)): return False @@ -145,15 +146,27 @@ # Check to see if a given path is the root of an svn repo over http. We verify # this by requesting a version-controlled URL we know can't exist and looking # for the svn-specific "not found" XML. -def httpcheck(path, proto): - return ('<m:human-readable errcode="160013">' in - urllib.urlopen('%s://%s/!svn/ver/0/.svn' % (proto, path)).read()) +def httpcheck(ui, path, proto): + try: + opener = urllib2.build_opener() + rsp = opener.open('%s://%s/!svn/ver/0/.svn' % (proto, path)) + return '<m:human-readable errcode="160013">' in rsp.read() + except urllib2.HTTPError, inst: + if inst.code == 404: + return False + # Except for 404 we cannot know for sure this is not an svn repo + ui.warn(_('svn: cannot probe remote repository, assume it could be ' + 'a subversion repository. Use --source if you know better.\n')) + return True + except: + # Could be urllib2.URLError if the URL is invalid or anything else. + return False protomap = {'http': httpcheck, 'https': httpcheck, 'file': filecheck, } -def issvnurl(url): +def issvnurl(ui, url): try: proto, path = url.split('://', 1) if proto == 'file': @@ -165,7 +178,7 @@ path = path.replace(os.sep, '/') check = protomap.get(proto, lambda p, p2: False) while '/' in path: - if check(path, proto): + if check(ui, path, proto): return True path = path.rsplit('/', 1)[0] return False @@ -191,7 +204,7 @@ if not (url.startswith('svn://') or url.startswith('svn+ssh://') or (os.path.exists(url) and os.path.exists(os.path.join(url, '.svn'))) or - issvnurl(url)): + issvnurl(ui, url)): raise NoRepo("%s does not look like a Subversion repo" % url) try: