Revert of Remove SVN and File support from gclient (patchset #4 id:60001 of https://codereview.chromium.org/2398493004/ )

Reason for revert:
The Chrome buildbots pass "--transitive" still. Removing the option causes them to fail to build.

Example:

https://uberchromegw.corp.google.com/i/chromeos.chrome/builders/x86-alex-tot-chrome-pfq-informational/builds/21555

Original issue's description:
> Remove SVN and File support from gclient
>
> FileImpl was only usable with SVN.
>
> R=maruel@chromium.org
> BUG=641588
>
> Committed: b3a24c3fd5

TBR=maruel@chromium.org,agable@chromium.org
# Skipping CQ checks because original CL landed less than 1 days ago.
NOPRESUBMIT=true
NOTREECHECKS=true
NOTRY=true
BUG=641588

Review-Url: https://codereview.chromium.org/2405173003
changes/18/399118/1
lpique 9 years ago committed by Commit bot
parent 7e269f0d05
commit 398a46ee09

@ -3,7 +3,7 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Meta checkout dependency manager for Git."""
"""Meta checkout manager supporting both Subversion and GIT."""
# Files
# .gclient : Current client configuration, written by 'config' command.
# Format is a Python script defining 'solutions', a list whose
@ -173,6 +173,29 @@ class GClientKeywords(object):
return 'From(%s, %s)' % (repr(self.module_name),
repr(self.sub_target_name))
class FileImpl(object):
"""Used to implement the File('') syntax which lets you sync a single file
from a SVN repo."""
def __init__(self, file_location):
self.file_location = file_location
def __str__(self):
return 'File("%s")' % self.file_location
def GetPath(self):
return os.path.split(self.file_location)[0]
def GetFilename(self):
rev_tokens = self.file_location.split('@')
return os.path.split(rev_tokens[0])[1]
def GetRevision(self):
rev_tokens = self.file_location.split('@')
if len(rev_tokens) > 1:
return rev_tokens[1]
return None
class VarImpl(object):
def __init__(self, custom_vars, local_scope):
self._custom_vars = custom_vars
@ -221,15 +244,24 @@ class DependencySettings(GClientKeywords):
self._custom_deps = custom_deps or {}
self._custom_hooks = custom_hooks or []
# TODO(iannucci): Remove this when all masters are correctly substituting
# the new blink url.
if (self._custom_vars.get('webkit_trunk', '') ==
'svn://svn-mirror.golo.chromium.org/webkit-readonly/trunk'):
new_url = 'svn://svn-mirror.golo.chromium.org/blink/trunk'
print('Overwriting Var("webkit_trunk") with %s' % new_url)
self._custom_vars['webkit_trunk'] = new_url
# Post process the url to remove trailing slashes.
if isinstance(self._url, basestring):
# urls are sometime incorrectly written as proto://host/path/@rev. Replace
# it to proto://host/path@rev.
self._url = self._url.replace('/@', '@')
elif not isinstance(self._url, (self.FromImpl, None.__class__)):
elif not isinstance(self._url,
(self.FromImpl, self.FileImpl, None.__class__)):
raise gclient_utils.Error(
('dependency url must be either a string, None, '
'or From() instead of %s') % self._url.__class__.__name__)
'File() or From() instead of %s') % self._url.__class__.__name__)
# Make any deps_file path platform-appropriate.
for sep in ['/', '\\']:
self._deps_file = self._deps_file.replace(sep, os.sep)
@ -502,6 +534,8 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
'relative DEPS entry \'%s\' must begin with a slash' % url)
# Create a scm just to query the full url.
parent_url = self.parent.parsed_url
if isinstance(parent_url, self.FileImpl):
parent_url = parent_url.file_location
scm = gclient_scm.CreateSCM(
parent_url, self.root.root_dir, None, self.outbuf)
parsed_url = scm.FullUrlForRelativeUrl(url)
@ -512,6 +546,12 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
(self.name, url, parsed_url))
return parsed_url
if isinstance(url, self.FileImpl):
logging.info(
'Dependency(%s).LateOverride(%s) -> %s (File)' %
(self.name, url, url))
return url
if url is None:
logging.info(
'Dependency(%s).LateOverride(%s) -> %s' % (self.name, url, url))
@ -602,6 +642,7 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
}
else:
global_scope = {
'File': self.FileImpl,
'From': self.FromImpl,
'Var': var.Lookup,
'deps_os': {},
@ -732,6 +773,41 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
self.add_dependency(dep)
self._mark_as_parsed(hooks)
def maybeGetParentRevision(self, command, options, parsed_url, parent):
"""Uses revision/timestamp of parent if no explicit revision was specified.
If we are performing an update and --transitive is set, use
- the parent's revision if 'self.url' is in the same repository
- the parent's timestamp otherwise
to update 'self.url'. The used revision/timestamp will be set in
'options.revision'.
If we have an explicit revision do nothing.
"""
if command == 'update' and options.transitive and not options.revision:
_, revision = gclient_utils.SplitUrlRevision(parsed_url)
if not revision:
options.revision = getattr(parent, '_used_revision', None)
if (options.revision and
not gclient_utils.IsDateRevision(options.revision)):
assert self.parent and self.parent.used_scm
# If this dependency is in the same repository as parent it's url will
# start with a slash. If so we take the parent revision instead of
# it's timestamp.
# (The timestamps of commits in google code are broken -- which can
# result in dependencies to be checked out at the wrong revision)
if self.url.startswith('/'):
if options.verbose:
print('Using parent\'s revision %s since we are in the same '
'repository.' % options.revision)
else:
parent_revision_date = self.parent.used_scm.GetRevisionDate(
options.revision)
options.revision = gclient_utils.MakeDateRevision(
parent_revision_date)
if options.verbose:
print('Using parent\'s revision date %s since we are in a '
'different repository.' % options.revision)
def findDepsFromNotAllowedHosts(self):
"""Returns a list of depenecies from not allowed hosts.
@ -766,17 +842,31 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
file_list = [] if not options.nohooks else None
revision_override = revision_overrides.pop(self.name, None)
if run_scm and parsed_url:
# Create a shallow copy to mutate revision.
options = copy.copy(options)
options.revision = revision_override
self._used_revision = options.revision
self._used_scm = gclient_scm.CreateSCM(
parsed_url, self.root.root_dir, self.name, self.outbuf,
out_cb=work_queue.out_cb)
self._got_revision = self._used_scm.RunCommand(command, options, args,
file_list)
if file_list:
file_list = [os.path.join(self.name, f.strip()) for f in file_list]
if isinstance(parsed_url, self.FileImpl):
# Special support for single-file checkout.
if not command in (None, 'cleanup', 'diff', 'pack', 'status'):
# Sadly, pylint doesn't realize that parsed_url is of FileImpl.
# pylint: disable=E1103
options.revision = parsed_url.GetRevision()
self._used_scm = gclient_scm.SVNWrapper(
parsed_url.GetPath(), self.root.root_dir, self.name,
out_cb=work_queue.out_cb)
self._used_scm.RunCommand('updatesingle',
options, args + [parsed_url.GetFilename()], file_list)
else:
# Create a shallow copy to mutate revision.
options = copy.copy(options)
options.revision = revision_override
self.maybeGetParentRevision(
command, options, parsed_url, self.parent)
self._used_revision = options.revision
self._used_scm = gclient_scm.CreateSCM(
parsed_url, self.root.root_dir, self.name, self.outbuf,
out_cb=work_queue.out_cb)
self._got_revision = self._used_scm.RunCommand(command, options, args,
file_list)
if file_list:
file_list = [os.path.join(self.name, f.strip()) for f in file_list]
# TODO(phajdan.jr): We should know exactly when the paths are absolute.
# Convert all absolute paths to relative.
@ -803,60 +893,61 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
work_queue.enqueue(s)
if command == 'recurse':
# Skip file only checkout.
scm = gclient_scm.GetScmName(parsed_url)
if not options.scm or scm in options.scm:
cwd = os.path.normpath(os.path.join(self.root.root_dir, self.name))
# Pass in the SCM type as an env variable. Make sure we don't put
# unicode strings in the environment.
env = os.environ.copy()
if scm:
env['GCLIENT_SCM'] = str(scm)
if parsed_url:
env['GCLIENT_URL'] = str(parsed_url)
env['GCLIENT_DEP_PATH'] = str(self.name)
if options.prepend_dir and scm == 'git':
print_stdout = False
def filter_fn(line):
"""Git-specific path marshaling. It is optimized for git-grep."""
def mod_path(git_pathspec):
match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec)
modified_path = os.path.join(self.name, match.group(2))
branch = match.group(1) or ''
return '%s%s' % (branch, modified_path)
match = re.match('^Binary file ([^\0]+) matches$', line)
if match:
print('Binary file %s matches\n' % mod_path(match.group(1)))
return
items = line.split('\0')
if len(items) == 2 and items[1]:
print('%s : %s' % (mod_path(items[0]), items[1]))
elif len(items) >= 2:
# Multiple null bytes or a single trailing null byte indicate
# git is likely displaying filenames only (such as with -l)
print('\n'.join(mod_path(path) for path in items if path))
else:
print(line)
else:
print_stdout = True
filter_fn = None
if parsed_url is None:
print('Skipped omitted dependency %s' % cwd, file=sys.stderr)
elif os.path.isdir(cwd):
try:
gclient_utils.CheckCallAndFilter(
args, cwd=cwd, env=env, print_stdout=print_stdout,
filter_fn=filter_fn,
)
except subprocess2.CalledProcessError:
if not options.ignore:
raise
else:
print('Skipped missing %s' % cwd, file=sys.stderr)
if not isinstance(parsed_url, self.FileImpl):
# Skip file only checkout.
scm = gclient_scm.GetScmName(parsed_url)
if not options.scm or scm in options.scm:
cwd = os.path.normpath(os.path.join(self.root.root_dir, self.name))
# Pass in the SCM type as an env variable. Make sure we don't put
# unicode strings in the environment.
env = os.environ.copy()
if scm:
env['GCLIENT_SCM'] = str(scm)
if parsed_url:
env['GCLIENT_URL'] = str(parsed_url)
env['GCLIENT_DEP_PATH'] = str(self.name)
if options.prepend_dir and scm == 'git':
print_stdout = False
def filter_fn(line):
"""Git-specific path marshaling. It is optimized for git-grep."""
def mod_path(git_pathspec):
match = re.match('^(\\S+?:)?([^\0]+)$', git_pathspec)
modified_path = os.path.join(self.name, match.group(2))
branch = match.group(1) or ''
return '%s%s' % (branch, modified_path)
match = re.match('^Binary file ([^\0]+) matches$', line)
if match:
print('Binary file %s matches\n' % mod_path(match.group(1)))
return
items = line.split('\0')
if len(items) == 2 and items[1]:
print('%s : %s' % (mod_path(items[0]), items[1]))
elif len(items) >= 2:
# Multiple null bytes or a single trailing null byte indicate
# git is likely displaying filenames only (such as with -l)
print('\n'.join(mod_path(path) for path in items if path))
else:
print(line)
else:
print_stdout = True
filter_fn = None
if parsed_url is None:
print('Skipped omitted dependency %s' % cwd, file=sys.stderr)
elif os.path.isdir(cwd):
try:
gclient_utils.CheckCallAndFilter(
args, cwd=cwd, env=env, print_stdout=print_stdout,
filter_fn=filter_fn,
)
except subprocess2.CalledProcessError:
if not options.ignore:
raise
else:
print('Skipped missing %s' % cwd, file=sys.stderr)
@gclient_utils.lockedmethod
@ -894,10 +985,11 @@ class Dependency(gclient_utils.WorkItem, DependencySettings):
# If "--force" was specified, run all hooks regardless of what files have
# changed.
if self.deps_hooks:
# TODO(maruel): If the user is using git, then we don't know
# TODO(maruel): If the user is using git or git-svn, then we don't know
# what files have changed so we always run all hooks. It'd be nice to fix
# that.
if (options.force or
isinstance(self.parsed_url, self.FileImpl) or
gclient_scm.GetScmName(self.parsed_url) in ('git', None) or
os.path.isdir(os.path.join(self.root.root_dir, self.name, '.git'))):
for hook_dict in self.deps_hooks:
@ -1181,7 +1273,9 @@ The local checkout in %(checkout_path)s reports:
%(actual_url)s (%(actual_scm)s)
You should ensure that the URL listed in .gclient is correct and either change
it or fix the checkout.
it or fix the checkout. If you're managing your own git checkout in
%(checkout_path)s but the URL in .gclient is for an svn repository, you probably
want to set 'managed': False in .gclient.
''' % {'checkout_path': os.path.join(self.root_dir, dep.name),
'expected_url': dep.url,
'expected_scm': gclient_scm.GetScmName(dep.url),
@ -1244,6 +1338,82 @@ it or fix the checkout.
self._options.config_filename),
self.config_content)
def MigrateConfigToGit(self, path, options):
svn_url_re = re.compile('^(https?://src\.chromium\.org/svn|'
'svn://svn\.chromium\.org/chrome)/'
'(trunk|branches/[^/]+)/src')
old_git_re = re.compile('^(https?://git\.chromium\.org|'
'ssh://([a-zA-Z_][a-zA-Z0-9_-]*@)?'
'gerrit\.chromium\.org(:2941[89])?)/'
'chromium/src\.git')
# Scan existing .gclient file for obsolete settings. It would be simpler
# to traverse self.dependencies, but working with the AST allows the code to
# dump an updated .gclient file that preserves the ordering of the original.
a = ast.parse(self.config_content, options.config_filename, 'exec')
modified = False
solutions = [elem for elem in a.body if 'solutions' in
[target.id for target in elem.targets]]
if not solutions:
return self
solutions = solutions[-1]
for solution in solutions.value.elts:
# Check for obsolete URL's
url_idx = ast_dict_index(solution, 'url')
if url_idx == -1:
continue
url_val = solution.values[url_idx]
if type(url_val) is not ast.Str:
continue
if (svn_url_re.match(url_val.s.strip())):
raise gclient_utils.Error(
"""
The chromium code repository has migrated completely to git.
Your SVN-based checkout is now obsolete; you need to create a brand-new
git checkout by following these instructions:
http://www.chromium.org/developers/how-tos/get-the-code
""")
if (old_git_re.match(url_val.s.strip())):
url_val.s = CHROMIUM_SRC_URL
modified = True
# Ensure deps_file is set to .DEPS.git. We enforce this here to smooth
# over switching between pre-git-migration and post-git-migration
# revisions.
# - For pre-migration revisions, .DEPS.git must be explicitly set.
# - For post-migration revisions, .DEPS.git is not present, so gclient
# will correctly fall back to DEPS.
if url_val.s == CHROMIUM_SRC_URL:
deps_file_idx = ast_dict_index(solution, 'deps_file')
if deps_file_idx != -1:
continue
solution.keys.append(ast.Str('deps_file'))
solution.values.append(ast.Str('.DEPS.git'))
modified = True
if not modified:
return self
print(
"""
WARNING: gclient detected an obsolete setting in your %s file. The file has
been automagically updated. The previous version is available at %s.old.
""" % (options.config_filename, options.config_filename))
# Replace existing .gclient with the updated version.
# Return a new GClient instance based on the new content.
new_content = ast2str(a)
dot_gclient_fn = os.path.join(path, options.config_filename)
try:
os.rename(dot_gclient_fn, dot_gclient_fn + '.old')
except OSError:
pass
with open(dot_gclient_fn, 'w') as fh:
fh.write(new_content)
client = GClient(path, options)
client.SetConfig(new_content)
return client
@staticmethod
def LoadCurrentConfig(options):
"""Searches for and loads a .gclient file relative to the current working
@ -1261,6 +1431,7 @@ it or fix the checkout.
client = GClient(path, options)
client.SetConfig(gclient_utils.FileRead(
os.path.join(path, options.config_filename)))
client = client.MigrateConfigToGit(path, options)
if (options.revisions and
len(client.dependencies) > 1 and
@ -1295,8 +1466,10 @@ it or fix the checkout.
# makes testing a bit too fun.
result = 'entries = {\n'
for entry in self.root.subtree(False):
result += ' %s: %s,\n' % (pprint.pformat(entry.name),
pprint.pformat(entry.parsed_url))
# Skip over File() dependencies as we can't version them.
if not isinstance(entry.parsed_url, self.FileImpl):
result += ' %s: %s,\n' % (pprint.pformat(entry.name),
pprint.pformat(entry.parsed_url))
result += '}\n'
file_path = os.path.join(self.root_dir, self._options.entries_filename)
logging.debug(result)
@ -1426,12 +1599,17 @@ it or fix the checkout.
prev_url, self.root_dir, entry_fixed, self.outbuf)
# Check to see if this directory is now part of a higher-up checkout.
# The directory might be part of a git OR svn checkout.
scm_root = None
try:
scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(scm.checkout_path)
except subprocess2.CalledProcessError:
pass
if not scm_root:
scm_class = None
for scm_class in (gclient_scm.scm.GIT, gclient_scm.scm.SVN):
try:
scm_root = scm_class.GetCheckoutRoot(scm.checkout_path)
except subprocess2.CalledProcessError:
pass
if scm_root:
break
else:
logging.warning('Could not find checkout root for %s. Unable to '
'determine whether it is part of a higher-level '
'checkout, so not removing.' % entry)
@ -1442,14 +1620,14 @@ it or fix the checkout.
# If the subproject is a Git project, we need to remove its .git
# folder. Otherwise git operations on that folder will have different
# effects depending on the current working directory.
if os.path.abspath(scm_root) == os.path.abspath(e_dir):
if scm_class == gclient_scm.scm.GIT and (
os.path.abspath(scm_root) == os.path.abspath(e_dir)):
e_par_dir = os.path.join(e_dir, os.pardir)
if gclient_scm.scm.GIT.IsInsideWorkTree(e_par_dir):
par_scm_root = gclient_scm.scm.GIT.GetCheckoutRoot(e_par_dir)
if scm_class.IsInsideWorkTree(e_par_dir):
par_scm_root = scm_class.GetCheckoutRoot(e_par_dir)
# rel_e_dir : relative path of entry w.r.t. its parent repo.
rel_e_dir = os.path.relpath(e_dir, par_scm_root)
if gclient_scm.scm.GIT.IsDirectoryVersioned(
par_scm_root, rel_e_dir):
if scm_class.IsDirectoryVersioned(par_scm_root, rel_e_dir):
save_dir = scm.GetGitBackupDirPath()
# Remove any eventual stale backup dir for the same project.
if os.path.exists(save_dir):
@ -1462,7 +1640,7 @@ it or fix the checkout.
# In such case we want to cleanup any eventual stale files
# (coming from the old subproject) in order to end up with a
# clean checkout.
gclient_scm.scm.GIT.CleanupDir(par_scm_root, rel_e_dir)
scm_class.CleanupDir(par_scm_root, rel_e_dir)
assert not os.path.exists(os.path.join(e_dir, '.git'))
print(('\nWARNING: \'%s\' has been moved from DEPS to a higher '
'level checkout. The git folder containing all the local'
@ -1510,9 +1688,13 @@ it or fix the checkout.
"""Returns the revision-qualified SCM url for a Dependency."""
if dep.parsed_url is None:
return None
url, _ = gclient_utils.SplitUrlRevision(dep.parsed_url)
if isinstance(dep.parsed_url, self.FileImpl):
original_url = dep.parsed_url.file_location
else:
original_url = dep.parsed_url
url, _ = gclient_utils.SplitUrlRevision(original_url)
scm = gclient_scm.CreateSCM(
dep.parsed_url, self.root_dir, dep.name, self.outbuf)
original_url, self.root_dir, dep.name, self.outbuf)
if not os.path.isdir(scm.checkout_path):
return None
return '%s@%s' % (url, scm.revinfo(self._options, [], None))
@ -1596,9 +1778,9 @@ it or fix the checkout.
def CMDcleanup(parser, args):
"""DEPRECATED: SVN-only. Cleaned up all working copies.
"""Cleans up all working copies.
This is a no-op in Git.
Mostly svn-specific. Simply runs 'svn cleanup' for each module.
"""
parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
help='override deps for the specified (comma-separated) '
@ -1781,7 +1963,7 @@ def CMDconfig(parser, args):
def CMDpack(parser, args):
"""Generates a patch which can be applied at the root of the tree.
Internally, runs 'git diff' on each checked out module and
Internally, runs 'svn diff'/'git diff' on each checked out module and
dependencies, and performs minimal postprocessing of the output. The
resulting patch is printed to stdout and can be applied to a freshly
checked out tree via 'patch -p0 < patchfile'.
@ -1836,8 +2018,8 @@ os_deps, etc.)
{
"solutions" : {
"<name>": { # <name> is the posix-normalized path to the solution.
"revision": [<git id hex string>|null],
"scm": ["git"|null],
"revision": [<svn rev int>|<git id hex string>|null],
"scm": ["svn"|"git"|null],
}
}
}
@ -1864,6 +2046,11 @@ def CMDsync(parser, args):
'full checkout. (git only)')
parser.add_option('--with_tags', action='store_true',
help='Clone git tags in addition to the default refspecs.')
parser.add_option('-t', '--transitive', action='store_true',
help='When a revision is specified (in the DEPS file or '
'with the command-line flag), transitively update '
'the dependencies to the date of the given revision. '
'Only supported for SVN repositories.')
parser.add_option('-H', '--head', action='store_true',
help='skips any safesync_urls specified in '
'configured solutions and sync to head instead')
@ -1888,6 +2075,9 @@ def CMDsync(parser, args):
help='override deps for the specified (comma-separated) '
'platform(s); \'all\' will process all deps_os '
'references')
parser.add_option('-m', '--manually_grab_svn_rev', action='store_true',
help='Skip svn up whenever possible by requesting '
'actual HEAD revision from the repository')
parser.add_option('--upstream', action='store_true',
help='Make repo state match upstream branch.')
parser.add_option('--output-json',
@ -1961,7 +2151,7 @@ def CMDrevert(parser, args):
"""Reverts all modifications in every dependencies.
That's the nuclear option to get back to a 'clean' state. It removes anything
that shows up in git status."""
that shows up in svn status."""
parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
help='override deps for the specified (comma-separated) '
'platform(s); \'all\' will process all deps_os '
@ -2013,8 +2203,9 @@ def CMDrevinfo(parser, args):
This allows the capture of an overall 'revision' for the source tree that
can be used to reproduce the same tree in the future. It is only useful for
'unpinned dependencies', i.e. DEPS/deps references without a git hash.
A git branch name isn't 'pinned' since the actual commit can change.
'unpinned dependencies', i.e. DEPS/deps references without a svn revision
number or a git hash. A git branch name isn't 'pinned' since the actual
commit can change.
"""
parser.add_option('--deps', dest='deps_os', metavar='OS_LIST',
help='override deps for the specified (comma-separated) '
@ -2080,6 +2271,12 @@ class OptionParser(optparse.OptionParser):
jobs = 1
else:
jobs = max(8, gclient_utils.NumLocalCpus())
# cmp: 2013/06/19
# Temporary workaround to lower bot-load on SVN server.
# Bypassed if a bot_update flag is detected.
if (os.environ.get('CHROME_HEADLESS') == '1' and
not os.path.exists('update.flag')):
jobs = 1
self.add_option(
'-j', '--jobs', default=jobs, type='int',
@ -2130,6 +2327,8 @@ class OptionParser(optparse.OptionParser):
options.noprehooks = True
if not hasattr(options, 'deps_os'):
options.deps_os = None
if not hasattr(options, 'manually_grab_svn_rev'):
options.manually_grab_svn_rev = None
if not hasattr(options, 'force'):
options.force = None
return (options, args)

@ -392,6 +392,14 @@ class GitWrapper(SCMWrapper):
if managed:
self._DisableHooks()
if gclient_utils.IsDateRevision(revision):
# Date-revisions only work on git-repositories if the reflog hasn't
# expired yet. Use rev-list to get the corresponding revision.
# git rev-list -n 1 --before='time-stamp' branchname
if options.transitive:
self.Print('Warning: --transitive only works for SVN repositories.')
revision = default_rev
rev_str = ' at %s' % revision
files = [] if file_list is not None else None
@ -1484,6 +1492,12 @@ class SVNWrapper(SCMWrapper):
self.Print('You can pass --force to enable automatic removal.')
raise e
# Retrieve the current HEAD version because svn is slow at null updates.
if options.manually_grab_svn_rev and not revision:
from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL'])
revision = str(from_info_live['Revision'])
rev_str = ' at %s' % revision
if from_info['URL'].rstrip('/') != base_url.rstrip('/'):
# The repository url changed, need to switch.
try:
@ -1713,6 +1727,10 @@ class SVNWrapper(SCMWrapper):
new_command.append('--force')
if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
new_command.extend(('--accept', 'theirs-conflict'))
elif options.manually_grab_svn_rev:
new_command.append('--force')
if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
new_command.extend(('--accept', 'postpone'))
elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
new_command.extend(('--accept', 'postpone'))
return new_command

@ -244,13 +244,17 @@ class GclientTest(trial_dir.TestCase):
obj.dependencies[0], 'foo/dir2',
gclient.GClientKeywords.FromImpl('bar'), None, None, None, None,
None, 'DEPS', True, False),
gclient.Dependency(
obj.dependencies[0], 'foo/dir3',
gclient.GClientKeywords.FileImpl('url'), None, None, None, None,
None, 'DEPS', True, False),
],
[])
# Make sure __str__() works fine.
# pylint: disable=W0212
obj.dependencies[0]._file_list.append('foo')
str_obj = str(obj)
self.assertEquals(370, len(str_obj), '%d\n%s' % (len(str_obj), str_obj))
self.assertEquals(471, len(str_obj), '%d\n%s' % (len(str_obj), str_obj))
def testHooks(self):
topdir = self.root_dir

Loading…
Cancel
Save