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
experimental/szager/collated-output
bauerb@chromium.org 15 years ago
parent 5c8c6de7e5
commit 866276c2ec

@ -101,6 +101,47 @@ def FixUrl(server):
return 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): class Settings(object):
def __init__(self): def __init__(self):
self.default_server = None self.default_server = None
@ -193,14 +234,26 @@ class Settings(object):
remote = match.group(1) remote = match.group(1)
base_url = match.group(2) base_url = match.group(2)
fetch_spec = RunGit( fetch_spec = RunGit(
['config', 'svn-remote.'+remote+'.fetch']).strip().split(':') ['config', 'svn-remote.%s.fetch' % remote],
if fetch_spec[0]: error_ok=True).strip()
full_url = base_url + '/' + fetch_spec[0] if fetch_spec:
else: self.svn_branch = MatchSvnGlob(url, base_url, fetch_spec, False)
full_url = base_url if self.svn_branch:
if full_url == url: break
self.svn_branch = fetch_spec[1] branch_spec = RunGit(
break ['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: if not self.svn_branch:
DieWithError('Can\'t guess svn branch -- try specifying it on the ' DieWithError('Can\'t guess svn branch -- try specifying it on the '

@ -5,6 +5,8 @@ set -e
PWD=`pwd` PWD=`pwd`
REPO_URL=file://$PWD/svnrepo REPO_URL=file://$PWD/svnrepo
TRUNK_URL=$REPO_URL/trunk
BRANCH_URL=$REPO_URL/branches/some_branch
GITREPO_PATH=$PWD/gitrepo GITREPO_PATH=$PWD/gitrepo
GITREPO_URL=file://$GITREPO_PATH GITREPO_URL=file://$GITREPO_PATH
GIT_CL=$PWD/../git-cl GIT_CL=$PWD/../git-cl
@ -14,12 +16,13 @@ setup_initsvn() {
echo "Setting up test SVN repo..." echo "Setting up test SVN repo..."
rm -rf svnrepo rm -rf svnrepo
svnadmin create svnrepo svnadmin create svnrepo
# Need this in order for Mac SnowLeopard to work # Need this in order for Mac SnowLeopard to work
echo "enable-rep-sharing = false" >> svnrepo/db/fsfs.conf echo "enable-rep-sharing = false" >> svnrepo/db/fsfs.conf
svn mkdir -q -m 'creating trunk' --parents $TRUNK_URL
rm -rf svn rm -rf svn
svn co -q $REPO_URL svn svn co -q $TRUNK_URL svn
( (
cd svn cd svn
echo "test" > test echo "test" > test
@ -28,6 +31,8 @@ setup_initsvn() {
echo "test2" >> test echo "test2" >> test
svn commit -q -m "second commit" 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. # Set up a git-svn checkout of the repo.
@ -36,7 +41,7 @@ setup_gitsvn() {
rm -rf git-svn rm -rf git-svn
# There appears to be no way to make git-svn completely shut up, so we # There appears to be no way to make git-svn completely shut up, so we
# redirect its output. # 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. # Set up a git repo that has a few commits to master.

@ -0,0 +1,32 @@
#!/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: except gclient_utils.CheckCallError:
return False 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 @staticmethod
def GetSVNBranch(cwd): def GetSVNBranch(cwd):
"""Returns the svn branch name if found.""" """Returns the svn branch name if found."""
@ -189,15 +231,33 @@ class GIT(object):
if match: if match:
remote = match.group(1) remote = match.group(1)
base_url = match.group(2) base_url = match.group(2)
fetch_spec = GIT.Capture( try:
['config', 'svn-remote.%s.fetch' % remote], fetch_spec = GIT.Capture(
cwd=cwd).strip().split(':') ['config', 'svn-remote.%s.fetch' % remote],
if fetch_spec[0]: cwd=cwd).strip()
full_url = base_url + '/' + fetch_spec[0] branch = GIT.MatchSvnGlob(url, base_url, fetch_spec, False)
else: except gclient_utils.CheckCallError:
full_url = base_url branch = None
if full_url == url: if branch:
return fetch_spec[1] 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 @staticmethod
def FetchUpstreamTuple(cwd): def FetchUpstreamTuple(cwd):

@ -53,7 +53,7 @@ class GitWrapperTestCase(BaseSCMTestCase):
'FetchUpstreamTuple', 'FetchUpstreamTuple',
'GenerateDiff', 'GetBranch', 'GetBranchRef', 'GetCheckoutRoot', 'GenerateDiff', 'GetBranch', 'GetBranchRef', 'GetCheckoutRoot',
'GetDifferentFiles', 'GetEmail', 'GetPatchName', 'GetSVNBranch', 'GetDifferentFiles', 'GetEmail', 'GetPatchName', 'GetSVNBranch',
'GetUpstreamBranch', 'IsGitSvn', 'ShortBranchName', 'GetUpstreamBranch', 'IsGitSvn', 'MatchSvnGlob', 'ShortBranchName',
] ]
# If this test fails, you should add the relevant test. # If this test fails, you should add the relevant test.
self.compareMembers(scm.GIT, members) self.compareMembers(scm.GIT, members)
@ -65,6 +65,17 @@ class GitWrapperTestCase(BaseSCMTestCase):
self.mox.ReplayAll() self.mox.ReplayAll()
self.assertEqual(scm.GIT.GetEmail(self.root_dir), 'mini@me.com') 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): class SVNTestCase(BaseSCMTestCase):
def setUp(self): def setUp(self):

Loading…
Cancel
Save