Commit 866276c2 authored by bauerb@chromium.org's avatar bauerb@chromium.org

Add support for wildcards in svn remote configuration.

BUG=none
TEST=manual

Review URL: http://codereview.chromium.org/6598068

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@78741 0039d316-1c4b-4281-b951-d872f2087c98
parent 5c8c6de7
......@@ -101,6 +101,47 @@ def FixUrl(server):
return server
def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards):
"""Return the corresponding git ref if |base_url| together with |glob_spec|
matches the full |url|.
If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below).
"""
fetch_suburl, as_ref = glob_spec.split(':')
if allow_wildcards:
glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl)
if glob_match:
# Parse specs like "branches/*/src:refs/remotes/svn/*" or
# "branches/{472,597,648}/src:refs/remotes/svn/*".
branch_re = re.escape(base_url)
if glob_match.group(1):
branch_re += '/' + re.escape(glob_match.group(1))
wildcard = glob_match.group(2)
if wildcard == '*':
branch_re += '([^/]*)'
else:
# Escape and replace surrounding braces with parentheses and commas
# with pipe symbols.
wildcard = re.escape(wildcard)
wildcard = re.sub('^\\\\{', '(', wildcard)
wildcard = re.sub('\\\\,', '|', wildcard)
wildcard = re.sub('\\\\}$', ')', wildcard)
branch_re += wildcard
if glob_match.group(3):
branch_re += re.escape(glob_match.group(3))
match = re.match(branch_re, url)
if match:
return re.sub('\*$', match.group(1), as_ref)
# Parse specs like "trunk/src:refs/remotes/origin/trunk".
if fetch_suburl:
full_url = base_url + '/' + fetch_suburl
else:
full_url = base_url
if full_url == url:
return as_ref
return None
class Settings(object):
def __init__(self):
self.default_server = None
......@@ -193,14 +234,26 @@ class Settings(object):
remote = match.group(1)
base_url = match.group(2)
fetch_spec = RunGit(
['config', 'svn-remote.'+remote+'.fetch']).strip().split(':')
if fetch_spec[0]:
full_url = base_url + '/' + fetch_spec[0]
else:
full_url = base_url
if full_url == url:
self.svn_branch = fetch_spec[1]
break
['config', 'svn-remote.%s.fetch' % remote],
error_ok=True).strip()
if fetch_spec:
self.svn_branch = MatchSvnGlob(url, base_url, fetch_spec, False)
if self.svn_branch:
break
branch_spec = RunGit(
['config', 'svn-remote.%s.branches' % remote],
error_ok=True).strip()
if branch_spec:
self.svn_branch = MatchSvnGlob(url, base_url, branch_spec, True)
if self.svn_branch:
break
tag_spec = RunGit(
['config', 'svn-remote.%s.tags' % remote],
error_ok=True).strip()
if tag_spec:
self.svn_branch = MatchSvnGlob(url, base_url, tag_spec, True)
if self.svn_branch:
break
if not self.svn_branch:
DieWithError('Can\'t guess svn branch -- try specifying it on the '
......
......@@ -5,6 +5,8 @@ set -e
PWD=`pwd`
REPO_URL=file://$PWD/svnrepo
TRUNK_URL=$REPO_URL/trunk
BRANCH_URL=$REPO_URL/branches/some_branch
GITREPO_PATH=$PWD/gitrepo
GITREPO_URL=file://$GITREPO_PATH
GIT_CL=$PWD/../git-cl
......@@ -14,12 +16,13 @@ setup_initsvn() {
echo "Setting up test SVN repo..."
rm -rf svnrepo
svnadmin create svnrepo
# Need this in order for Mac SnowLeopard to work
echo "enable-rep-sharing = false" >> svnrepo/db/fsfs.conf
svn mkdir -q -m 'creating trunk' --parents $TRUNK_URL
rm -rf svn
svn co -q $REPO_URL svn
svn co -q $TRUNK_URL svn
(
cd svn
echo "test" > test
......@@ -28,6 +31,8 @@ setup_initsvn() {
echo "test2" >> test
svn commit -q -m "second commit"
)
svn cp -q -m 'branching' --parents $TRUNK_URL $BRANCH_URL
}
# Set up a git-svn checkout of the repo.
......@@ -36,7 +41,7 @@ setup_gitsvn() {
rm -rf git-svn
# There appears to be no way to make git-svn completely shut up, so we
# redirect its output.
git svn -q clone $REPO_URL git-svn >/dev/null 2>&1
git svn -q clone -s $REPO_URL git-svn >/dev/null 2>&1
}
# Set up a git repo that has a few commits to master.
......
#!/bin/bash
# Check guessing the svn upstream branch.
set -e
. ./test-lib.sh
setup_initsvn
setup_gitsvn
(
set -e
cd git-svn
git config rietveld.server localhost:8080
for ref in refs/remotes/trunk refs/remotes/some_branch; do
git checkout -q -B feature_branch $ref
test_expect_success "Guessing upstream branch for $ref" \
"$GIT_CL upstream | egrep -q '^$ref$'"
git checkout -q master
done
)
SUCCESS=$?
cleanup
if [ $SUCCESS == 0 ]; then
echo PASS
fi
......@@ -157,6 +157,48 @@ class GIT(object):
except gclient_utils.CheckCallError:
return False
@staticmethod
def MatchSvnGlob(url, base_url, glob_spec, allow_wildcards):
"""Return the corresponding git ref if |base_url| together with |glob_spec|
matches the full |url|.
If |allow_wildcards| is true, |glob_spec| can contain wildcards (see below).
"""
fetch_suburl, as_ref = glob_spec.split(':')
if allow_wildcards:
glob_match = re.match('(.+/)?(\*|{[^/]*})(/.+)?', fetch_suburl)
if glob_match:
# Parse specs like "branches/*/src:refs/remotes/svn/*" or
# "branches/{472,597,648}/src:refs/remotes/svn/*".
branch_re = re.escape(base_url)
if glob_match.group(1):
branch_re += '/' + re.escape(glob_match.group(1))
wildcard = glob_match.group(2)
if wildcard == '*':
branch_re += '([^/]*)'
else:
# Escape and replace surrounding braces with parentheses and commas
# with pipe symbols.
wildcard = re.escape(wildcard)
wildcard = re.sub('^\\\\{', '(', wildcard)
wildcard = re.sub('\\\\,', '|', wildcard)
wildcard = re.sub('\\\\}$', ')', wildcard)
branch_re += wildcard
if glob_match.group(3):
branch_re += re.escape(glob_match.group(3))
match = re.match(branch_re, url)
if match:
return re.sub('\*$', match.group(1), as_ref)
# Parse specs like "trunk/src:refs/remotes/origin/trunk".
if fetch_suburl:
full_url = base_url + '/' + fetch_suburl
else:
full_url = base_url
if full_url == url:
return as_ref
return None
@staticmethod
def GetSVNBranch(cwd):
"""Returns the svn branch name if found."""
......@@ -189,15 +231,33 @@ class GIT(object):
if match:
remote = match.group(1)
base_url = match.group(2)
fetch_spec = GIT.Capture(
['config', 'svn-remote.%s.fetch' % remote],
cwd=cwd).strip().split(':')
if fetch_spec[0]:
full_url = base_url + '/' + fetch_spec[0]
else:
full_url = base_url
if full_url == url:
return fetch_spec[1]
try:
fetch_spec = GIT.Capture(
['config', 'svn-remote.%s.fetch' % remote],
cwd=cwd).strip()
branch = GIT.MatchSvnGlob(url, base_url, fetch_spec, False)
except gclient_utils.CheckCallError:
branch = None
if branch:
return branch
try:
branch_spec = GIT.Capture(
['config', 'svn-remote.%s.branches' % remote],
cwd=cwd).strip()
branch = GIT.MatchSvnGlob(url, base_url, branch_spec, True)
except gclient_utils.CheckCallError:
branch = None
if branch:
return branch
try:
tag_spec = GIT.Capture(
['config', 'svn-remote.%s.tags' % remote],
cwd=cwd).strip()
branch = GIT.MatchSvnGlob(url, base_url, tag_spec, True)
except gclient_utils.CheckCallError:
branch = None
if branch:
return branch
@staticmethod
def FetchUpstreamTuple(cwd):
......
......@@ -53,7 +53,7 @@ class GitWrapperTestCase(BaseSCMTestCase):
'FetchUpstreamTuple',
'GenerateDiff', 'GetBranch', 'GetBranchRef', 'GetCheckoutRoot',
'GetDifferentFiles', 'GetEmail', 'GetPatchName', 'GetSVNBranch',
'GetUpstreamBranch', 'IsGitSvn', 'ShortBranchName',
'GetUpstreamBranch', 'IsGitSvn', 'MatchSvnGlob', 'ShortBranchName',
]
# If this test fails, you should add the relevant test.
self.compareMembers(scm.GIT, members)
......@@ -65,6 +65,17 @@ class GitWrapperTestCase(BaseSCMTestCase):
self.mox.ReplayAll()
self.assertEqual(scm.GIT.GetEmail(self.root_dir), 'mini@me.com')
def testMatchSvnGlob(self):
self.assertEquals(scm.GIT.MatchSvnGlob(
'svn://svn.chromium.org/chrome/trunk/src',
'svn://svn.chromium.org/chrome',
'trunk/src:refs/remotes/origin/trunk',
False), 'refs/remotes/origin/trunk')
self.assertEquals(scm.GIT.MatchSvnGlob(
'https://v8.googlecode.com/svn/branches/bleeding_edge',
'https://v8.googlecode.com/svn',
'branches/*:refs/remotes/*',
True), 'refs/remotes/bleeding_edge')
class SVNTestCase(BaseSCMTestCase):
def setUp(self):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment