| Index: gclient_scm.py
|
| diff --git a/gclient_scm.py b/gclient_scm.py
|
| index cb8e6f31746403e63f9f3fa17e16102cc23cacfd..d46d47eef0c514a72b30da7e159822fafd40c034 100644
|
| --- a/gclient_scm.py
|
| +++ b/gclient_scm.py
|
| @@ -37,14 +37,14 @@ class NoUsableRevError(gclient_utils.Error):
|
| class DiffFiltererWrapper(object):
|
| """Simple base class which tracks which file is being diffed and
|
| replaces instances of its file name in the original and
|
| - working copy lines of the svn/git diff output."""
|
| + working copy lines of the git diff output."""
|
| index_string = None
|
| original_prefix = "--- "
|
| working_prefix = "+++ "
|
|
|
| def __init__(self, relpath, print_func):
|
| # Note that we always use '/' as the path separator to be
|
| - # consistent with svn's cygwin-style output on Windows
|
| + # consistent with cygwin-style output on Windows
|
| self._relpath = relpath.replace("\\", "/")
|
| self._current_file = None
|
| self._print_func = print_func
|
| @@ -70,10 +70,6 @@ class DiffFiltererWrapper(object):
|
| self._print_func(line)
|
|
|
|
|
| -class SvnDiffFilterer(DiffFiltererWrapper):
|
| - index_string = "Index: "
|
| -
|
| -
|
| class GitDiffFilterer(DiffFiltererWrapper):
|
| index_string = "diff --git "
|
|
|
| @@ -90,26 +86,20 @@ class GitDiffFilterer(DiffFiltererWrapper):
|
| # Factory Method for SCM wrapper creation
|
|
|
| def GetScmName(url):
|
| - if url:
|
| - url, _ = gclient_utils.SplitUrlRevision(url)
|
| - if (url.startswith('git://') or url.startswith('ssh://') or
|
| - url.startswith('git+http://') or url.startswith('git+https://') or
|
| - url.endswith('.git') or url.startswith('sso://') or
|
| - 'googlesource' in url):
|
| - return 'git'
|
| - elif (url.startswith('http://') or url.startswith('https://') or
|
| - url.startswith('svn://') or url.startswith('svn+ssh://')):
|
| - return 'svn'
|
| - elif url.startswith('file://'):
|
| - if url.endswith('.git'):
|
| - return 'git'
|
| - return 'svn'
|
| + if not url:
|
| + return None
|
| + url, _ = gclient_utils.SplitUrlRevision(url)
|
| + if url.endswith('.git'):
|
| + return 'git'
|
| + protocol = url.split('://')[0]
|
| + if protocol in (
|
| + 'file', 'git', 'git+http', 'git+https', 'http', 'https', 'ssh', 'sso'):
|
| + return 'git'
|
| return None
|
|
|
|
|
| def CreateSCM(url, root_dir=None, relpath=None, out_fh=None, out_cb=None):
|
| SCM_MAP = {
|
| - 'svn' : SVNWrapper,
|
| 'git' : GitWrapper,
|
| }
|
|
|
| @@ -192,10 +182,6 @@ class SCMWrapper(object):
|
| actual_remote_url.replace('\\', '/')):
|
| actual_remote_url = self._get_first_remote_url(mirror.mirror_path)
|
| return actual_remote_url
|
| -
|
| - # Svn
|
| - if os.path.exists(os.path.join(self.checkout_path, '.svn')):
|
| - return scm.SVN.CaptureLocalInfo([], self.checkout_path)['URL']
|
| return None
|
|
|
| def DoesRemoteURLMatch(self, options):
|
| @@ -210,7 +196,7 @@ class SCMWrapper(object):
|
| == gclient_utils.SplitUrlRevision(self.url)[0].rstrip('/'))
|
| else:
|
| # This may occur if the self.checkout_path exists but does not contain a
|
| - # valid git or svn checkout.
|
| + # valid git checkout.
|
| return False
|
|
|
| def _DeleteOrMove(self, force):
|
| @@ -503,7 +489,7 @@ class GitWrapper(SCMWrapper):
|
| # 0) HEAD is detached. Probably from our initial clone.
|
| # - make sure HEAD is contained by a named ref, then update.
|
| # Cases 1-4. HEAD is a branch.
|
| - # 1) current branch is not tracking a remote branch (could be git-svn)
|
| + # 1) current branch is not tracking a remote branch
|
| # - try to rebase onto the new hash or branch
|
| # 2) current branch is tracking a remote branch with local committed
|
| # changes, but the DEPS file switched to point to a hash
|
| @@ -573,22 +559,15 @@ class GitWrapper(SCMWrapper):
|
| self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False)
|
| elif current_type == 'hash':
|
| # case 1
|
| - if scm.GIT.IsGitSvn(self.checkout_path) and upstream_branch is not None:
|
| - # Our git-svn branch (upstream_branch) is our upstream
|
| - self._AttemptRebase(upstream_branch, files, options,
|
| - newbase=revision, printed_path=printed_path,
|
| - merge=options.merge)
|
| - printed_path = True
|
| - else:
|
| - # Can't find a merge-base since we don't know our upstream. That makes
|
| - # this command VERY likely to produce a rebase failure. For now we
|
| - # assume origin is our upstream since that's what the old behavior was.
|
| - upstream_branch = self.remote
|
| - if options.revision or deps_revision:
|
| - upstream_branch = revision
|
| - self._AttemptRebase(upstream_branch, files, options,
|
| - printed_path=printed_path, merge=options.merge)
|
| - printed_path = True
|
| + # Can't find a merge-base since we don't know our upstream. That makes
|
| + # this command VERY likely to produce a rebase failure. For now we
|
| + # assume origin is our upstream since that's what the old behavior was.
|
| + upstream_branch = self.remote
|
| + if options.revision or deps_revision:
|
| + upstream_branch = revision
|
| + self._AttemptRebase(upstream_branch, files, options,
|
| + printed_path=printed_path, merge=options.merge)
|
| + printed_path = True
|
| elif rev_type == 'hash':
|
| # case 2
|
| self._AttemptRebase(upstream_branch, files, options,
|
| @@ -788,16 +767,13 @@ class GitWrapper(SCMWrapper):
|
| except subprocess2.CalledProcessError:
|
| merge_base = []
|
| self._Run(['diff', '--name-status'] + merge_base, options,
|
| - stdout=self.out_fh)
|
| + stdout=self.out_fh, always=options.verbose)
|
| if file_list is not None:
|
| files = self._Capture(['diff', '--name-only'] + merge_base).split()
|
| file_list.extend([os.path.join(self.checkout_path, f) for f in files])
|
|
|
| def GetUsableRev(self, rev, options):
|
| - """Finds a useful revision for this repository.
|
| -
|
| - If SCM is git-svn and the head revision is less than |rev|, git svn fetch
|
| - will be called on the source."""
|
| + """Finds a useful revision for this repository."""
|
| sha1 = None
|
| if not os.path.isdir(self.checkout_path):
|
| raise NoUsableRevError(
|
| @@ -807,56 +783,23 @@ class GitWrapper(SCMWrapper):
|
| 'For more info, see: '
|
| 'http://code.google.com/p/chromium/wiki/UsingNewGit'
|
| '#Initial_checkout' ) % rev)
|
| - elif rev.isdigit() and len(rev) < 7:
|
| - # Handles an SVN rev. As an optimization, only verify an SVN revision as
|
| - # [0-9]{1,6} for now to avoid making a network request.
|
| - if scm.GIT.IsGitSvn(cwd=self.checkout_path):
|
| - local_head = scm.GIT.GetGitSvnHeadRev(cwd=self.checkout_path)
|
| - if not local_head or local_head < int(rev):
|
| - try:
|
| - logging.debug('Looking for git-svn configuration optimizations.')
|
| - if scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
|
| - cwd=self.checkout_path):
|
| - self._Fetch(options)
|
| - except subprocess2.CalledProcessError:
|
| - logging.debug('git config --get svn-remote.svn.fetch failed, '
|
| - 'ignoring possible optimization.')
|
| - if options.verbose:
|
| - self.Print('Running git svn fetch. This might take a while.\n')
|
| - scm.GIT.Capture(['svn', 'fetch'], cwd=self.checkout_path)
|
| - try:
|
| - sha1 = scm.GIT.GetBlessedSha1ForSvnRev(
|
| - cwd=self.checkout_path, rev=rev)
|
| - except gclient_utils.Error, e:
|
| - sha1 = e.message
|
| - self.Print('Warning: Could not find a git revision with accurate\n'
|
| - '.DEPS.git that maps to SVN revision %s. Sync-ing to\n'
|
| - 'the closest sane git revision, which is:\n'
|
| - ' %s\n' % (rev, e.message))
|
| - if not sha1:
|
| - raise NoUsableRevError(
|
| - ( 'It appears that either your git-svn remote is incorrectly\n'
|
| - 'configured or the revision in your safesync_url is\n'
|
| - 'higher than git-svn remote\'s HEAD as we couldn\'t find a\n'
|
| - 'corresponding git hash for SVN rev %s.' ) % rev)
|
| +
|
| + if scm.GIT.IsValidRevision(cwd=self.checkout_path, rev=rev):
|
| + sha1 = rev
|
| else:
|
| + # May exist in origin, but we don't have it yet, so fetch and look
|
| + # again.
|
| + self._Fetch(options)
|
| if scm.GIT.IsValidRevision(cwd=self.checkout_path, rev=rev):
|
| sha1 = rev
|
| - else:
|
| - # May exist in origin, but we don't have it yet, so fetch and look
|
| - # again.
|
| - self._Fetch(options)
|
| - if scm.GIT.IsValidRevision(cwd=self.checkout_path, rev=rev):
|
| - sha1 = rev
|
|
|
| if not sha1:
|
| raise NoUsableRevError(
|
| - ( 'We could not find a valid hash for safesync_url response "%s".\n'
|
| - 'Safesync URLs with a git checkout currently require a git-svn\n'
|
| - 'remote or a safesync_url that provides git sha1s. Please add a\n'
|
| - 'git-svn remote or change your safesync_url. For more info, see:\n'
|
| - 'http://code.google.com/p/chromium/wiki/UsingNewGit'
|
| - '#Initial_checkout' ) % rev)
|
| + ('We could not find a valid hash for safesync_url response "%s".\n'
|
| + 'Please ensure that your safesync_url provides git sha1 hashes.\n'
|
| + 'For more info, see:\n'
|
| + 'http://code.google.com/p/chromium/wiki/UsingNewGit#Initial_checkout'
|
| + ) % rev)
|
|
|
| return sha1
|
|
|
| @@ -1239,480 +1182,3 @@ class GitWrapper(SCMWrapper):
|
| gclient_utils.CheckCallAndFilterAndHeader(cmd, env=env, **kwargs)
|
| else:
|
| gclient_utils.CheckCallAndFilter(cmd, env=env, **kwargs)
|
| -
|
| -
|
| -class SVNWrapper(SCMWrapper):
|
| - """ Wrapper for SVN """
|
| - name = 'svn'
|
| - _PRINTED_DEPRECATION = False
|
| -
|
| - _MESSAGE = (
|
| - 'Oh hai! You are using subversion. Chrome infra is eager to get rid of',
|
| - 'svn support so please switch to git.',
|
| - 'Tracking bug: http://crbug.com/475320',
|
| - 'If you are a project owner, you may request git migration assistance at: ',
|
| - ' https://code.google.com/p/chromium/issues/entry?template=Infra-Git')
|
| -
|
| - def __init__(self, *args, **kwargs):
|
| - super(SVNWrapper, self).__init__(*args, **kwargs)
|
| - suppress_deprecated_notice = os.environ.get(
|
| - 'SUPPRESS_DEPRECATED_SVN_NOTICE', False)
|
| - if not SVNWrapper._PRINTED_DEPRECATION and not suppress_deprecated_notice:
|
| - SVNWrapper._PRINTED_DEPRECATION = True
|
| - sys.stderr.write('\n'.join(self._MESSAGE) + '\n')
|
| -
|
| - @staticmethod
|
| - def BinaryExists():
|
| - """Returns true if the command exists."""
|
| - try:
|
| - result, version = scm.SVN.AssertVersion('1.4')
|
| - if not result:
|
| - raise gclient_utils.Error('SVN version is older than 1.4: %s' % version)
|
| - return result
|
| - except OSError:
|
| - return False
|
| -
|
| - def GetCheckoutRoot(self):
|
| - return scm.SVN.GetCheckoutRoot(self.checkout_path)
|
| -
|
| - def GetRevisionDate(self, revision):
|
| - """Returns the given revision's date in ISO-8601 format (which contains the
|
| - time zone)."""
|
| - date = scm.SVN.Capture(
|
| - ['propget', '--revprop', 'svn:date', '-r', revision],
|
| - os.path.join(self.checkout_path, '.'))
|
| - return date.strip()
|
| -
|
| - def cleanup(self, options, args, _file_list):
|
| - """Cleanup working copy."""
|
| - self._Run(['cleanup'] + args, options)
|
| -
|
| - def diff(self, options, args, _file_list):
|
| - # NOTE: This function does not currently modify file_list.
|
| - if not os.path.isdir(self.checkout_path):
|
| - raise gclient_utils.Error('Directory %s is not present.' %
|
| - self.checkout_path)
|
| - self._Run(['diff'] + args, options)
|
| -
|
| - def pack(self, _options, args, _file_list):
|
| - """Generates a patch file which can be applied to the root of the
|
| - repository."""
|
| - if not os.path.isdir(self.checkout_path):
|
| - raise gclient_utils.Error('Directory %s is not present.' %
|
| - self.checkout_path)
|
| - gclient_utils.CheckCallAndFilter(
|
| - ['svn', 'diff', '-x', '--ignore-eol-style'] + args,
|
| - cwd=self.checkout_path,
|
| - print_stdout=False,
|
| - filter_fn=SvnDiffFilterer(self.relpath, print_func=self.Print).Filter)
|
| -
|
| - def update(self, options, args, file_list):
|
| - """Runs svn to update or transparently checkout the working copy.
|
| -
|
| - All updated files will be appended to file_list.
|
| -
|
| - Raises:
|
| - Error: if can't get URL for relative path.
|
| - """
|
| - # Only update if hg is not controlling the directory.
|
| - hg_path = os.path.join(self.checkout_path, '.hg')
|
| - if os.path.exists(hg_path):
|
| - self.Print('________ found .hg directory; skipping %s' % self.relpath)
|
| - return
|
| -
|
| - if args:
|
| - raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))
|
| -
|
| - # revision is the revision to match. It is None if no revision is specified,
|
| - # i.e. the 'deps ain't pinned'.
|
| - url, revision = gclient_utils.SplitUrlRevision(self.url)
|
| - # Keep the original unpinned url for reference in case the repo is switched.
|
| - base_url = url
|
| - managed = True
|
| - if options.revision:
|
| - # Override the revision number.
|
| - revision = str(options.revision)
|
| - if revision:
|
| - if revision != 'unmanaged':
|
| - forced_revision = True
|
| - # Reconstruct the url.
|
| - url = '%s@%s' % (url, revision)
|
| - rev_str = ' at %s' % revision
|
| - else:
|
| - managed = False
|
| - revision = None
|
| - else:
|
| - forced_revision = False
|
| - rev_str = ''
|
| -
|
| - exists = os.path.exists(self.checkout_path)
|
| - if exists and managed:
|
| - # Git is only okay if it's a git-svn checkout of the right repo.
|
| - if scm.GIT.IsGitSvn(self.checkout_path):
|
| - remote_url = scm.GIT.Capture(['config', '--local', '--get',
|
| - 'svn-remote.svn.url'],
|
| - cwd=self.checkout_path).rstrip()
|
| - if remote_url.rstrip('/') == base_url.rstrip('/'):
|
| - self.Print('\n_____ %s looks like a git-svn checkout. Skipping.'
|
| - % self.relpath)
|
| - return # TODO(borenet): Get the svn revision number?
|
| -
|
| - # Get the existing scm url and the revision number of the current checkout.
|
| - if exists and managed:
|
| - try:
|
| - from_info = scm.SVN.CaptureLocalInfo(
|
| - [], os.path.join(self.checkout_path, '.'))
|
| - except (gclient_utils.Error, subprocess2.CalledProcessError):
|
| - self._DeleteOrMove(options.force)
|
| - exists = False
|
| -
|
| - BASE_URLS = {
|
| - '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/',
|
| - '/blink/trunk': 'gs://chromium-svn-checkout/blink/',
|
| - }
|
| - WHITELISTED_ROOTS = [
|
| - 'svn://svn.chromium.org',
|
| - 'svn://svn-mirror.golo.chromium.org',
|
| - ]
|
| - if not exists:
|
| - try:
|
| - # Split out the revision number since it's not useful for us.
|
| - base_path = urlparse.urlparse(url).path.split('@')[0]
|
| - # Check to see if we're on a whitelisted root. We do this because
|
| - # only some svn servers have matching UUIDs.
|
| - local_parsed = urlparse.urlparse(url)
|
| - local_root = '%s://%s' % (local_parsed.scheme, local_parsed.netloc)
|
| - if ('CHROME_HEADLESS' in os.environ
|
| - and sys.platform == 'linux2' # TODO(hinoka): Enable for win/mac.
|
| - and base_path in BASE_URLS
|
| - and local_root in WHITELISTED_ROOTS):
|
| -
|
| - # Use a tarball for initial sync if we are on a bot.
|
| - # Get an unauthenticated gsutil instance.
|
| - gsutil = download_from_google_storage.Gsutil(
|
| - GSUTIL_DEFAULT_PATH, boto_path=os.devnull)
|
| -
|
| - gs_path = BASE_URLS[base_path]
|
| - _, out, _ = gsutil.check_call('ls', gs_path)
|
| - # So that we can get the most recent revision.
|
| - sorted_items = sorted(out.splitlines())
|
| - latest_checkout = sorted_items[-1]
|
| -
|
| - tempdir = tempfile.mkdtemp()
|
| - self.Print('Downloading %s...' % latest_checkout)
|
| - code, out, err = gsutil.check_call('cp', latest_checkout, tempdir)
|
| - if code:
|
| - self.Print('%s\n%s' % (out, err))
|
| - raise Exception()
|
| - filename = latest_checkout.split('/')[-1]
|
| - tarball = os.path.join(tempdir, filename)
|
| - self.Print('Unpacking into %s...' % self.checkout_path)
|
| - gclient_utils.safe_makedirs(self.checkout_path)
|
| - # TODO(hinoka): Use 7z for windows.
|
| - cmd = ['tar', '--extract', '--ungzip',
|
| - '--directory', self.checkout_path,
|
| - '--file', tarball]
|
| - gclient_utils.CheckCallAndFilter(
|
| - cmd, stdout=sys.stdout, print_stdout=True)
|
| -
|
| - self.Print('Deleting temp file')
|
| - gclient_utils.rmtree(tempdir)
|
| -
|
| - # Rewrite the repository root to match.
|
| - tarball_url = scm.SVN.CaptureLocalInfo(
|
| - ['.'], self.checkout_path)['Repository Root']
|
| - tarball_parsed = urlparse.urlparse(tarball_url)
|
| - tarball_root = '%s://%s' % (tarball_parsed.scheme,
|
| - tarball_parsed.netloc)
|
| -
|
| - if tarball_root != local_root:
|
| - self.Print('Switching repository root to %s' % local_root)
|
| - self._Run(['switch', '--relocate', tarball_root,
|
| - local_root, self.checkout_path],
|
| - options)
|
| - except Exception as e:
|
| - self.Print('We tried to get a source tarball but failed.')
|
| - self.Print('Resuming normal operations.')
|
| - self.Print(str(e))
|
| -
|
| - gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path))
|
| - # We need to checkout.
|
| - command = ['checkout', url, self.checkout_path]
|
| - command = self._AddAdditionalUpdateFlags(command, options, revision)
|
| - self._RunAndGetFileList(command, options, file_list, self._root_dir)
|
| - return self.Svnversion()
|
| -
|
| - if not managed:
|
| - self.Print(('________ unmanaged solution; skipping %s' % self.relpath))
|
| - if os.path.exists(os.path.join(self.checkout_path, '.svn')):
|
| - return self.Svnversion()
|
| - return
|
| -
|
| - if 'URL' not in from_info:
|
| - raise gclient_utils.Error(
|
| - ('gclient is confused. Couldn\'t get the url for %s.\n'
|
| - 'Try using @unmanaged.\n%s') % (
|
| - self.checkout_path, from_info))
|
| -
|
| - # Look for locked directories.
|
| - dir_info = scm.SVN.CaptureStatus(
|
| - None, os.path.join(self.checkout_path, '.'))
|
| - if any(d[0][2] == 'L' for d in dir_info):
|
| - try:
|
| - self._Run(['cleanup', self.checkout_path], options)
|
| - except subprocess2.CalledProcessError, e:
|
| - # Get the status again, svn cleanup may have cleaned up at least
|
| - # something.
|
| - dir_info = scm.SVN.CaptureStatus(
|
| - None, os.path.join(self.checkout_path, '.'))
|
| -
|
| - # Try to fix the failures by removing troublesome files.
|
| - for d in dir_info:
|
| - if d[0][2] == 'L':
|
| - if d[0][0] == '!' and options.force:
|
| - # We don't pass any files/directories to CaptureStatus and set
|
| - # cwd=self.checkout_path, so we should get relative paths here.
|
| - assert not os.path.isabs(d[1])
|
| - path_to_remove = os.path.normpath(
|
| - os.path.join(self.checkout_path, d[1]))
|
| - self.Print('Removing troublesome path %s' % path_to_remove)
|
| - gclient_utils.rmtree(path_to_remove)
|
| - else:
|
| - self.Print(
|
| - 'Not removing troublesome path %s automatically.' % d[1])
|
| - if d[0][0] == '!':
|
| - self.Print('You can pass --force to enable automatic removal.')
|
| - raise e
|
| -
|
| - if from_info['URL'].rstrip('/') != base_url.rstrip('/'):
|
| - # The repository url changed, need to switch.
|
| - try:
|
| - to_info = scm.SVN.CaptureRemoteInfo(url)
|
| - except (gclient_utils.Error, subprocess2.CalledProcessError):
|
| - # The url is invalid or the server is not accessible, it's safer to bail
|
| - # out right now.
|
| - raise gclient_utils.Error('This url is unreachable: %s' % url)
|
| - can_switch = ((from_info['Repository Root'] != to_info['Repository Root'])
|
| - and (from_info['UUID'] == to_info['UUID']))
|
| - if can_switch:
|
| - self.Print('_____ relocating %s to a new checkout' % self.relpath)
|
| - # We have different roots, so check if we can switch --relocate.
|
| - # Subversion only permits this if the repository UUIDs match.
|
| - # Perform the switch --relocate, then rewrite the from_url
|
| - # to reflect where we "are now." (This is the same way that
|
| - # Subversion itself handles the metadata when switch --relocate
|
| - # is used.) This makes the checks below for whether we
|
| - # can update to a revision or have to switch to a different
|
| - # branch work as expected.
|
| - # TODO(maruel): TEST ME !
|
| - command = ['switch', '--relocate',
|
| - from_info['Repository Root'],
|
| - to_info['Repository Root'],
|
| - self.relpath]
|
| - self._Run(command, options, cwd=self._root_dir)
|
| - from_info['URL'] = from_info['URL'].replace(
|
| - from_info['Repository Root'],
|
| - to_info['Repository Root'])
|
| - else:
|
| - if not options.force and not options.reset:
|
| - # Look for local modifications but ignore unversioned files.
|
| - for status in scm.SVN.CaptureStatus(None, self.checkout_path):
|
| - if status[0][0] != '?':
|
| - raise gclient_utils.Error(
|
| - ('Can\'t switch the checkout to %s; UUID don\'t match and '
|
| - 'there is local changes in %s. Delete the directory and '
|
| - 'try again.') % (url, self.checkout_path))
|
| - # Ok delete it.
|
| - self.Print('_____ switching %s to a new checkout' % self.relpath)
|
| - gclient_utils.rmtree(self.checkout_path)
|
| - # We need to checkout.
|
| - command = ['checkout', url, self.checkout_path]
|
| - command = self._AddAdditionalUpdateFlags(command, options, revision)
|
| - self._RunAndGetFileList(command, options, file_list, self._root_dir)
|
| - return self.Svnversion()
|
| -
|
| - # If the provided url has a revision number that matches the revision
|
| - # number of the existing directory, then we don't need to bother updating.
|
| - if not options.force and str(from_info['Revision']) == revision:
|
| - if options.verbose or not forced_revision:
|
| - self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False)
|
| - else:
|
| - command = ['update', self.checkout_path]
|
| - command = self._AddAdditionalUpdateFlags(command, options, revision)
|
| - self._RunAndGetFileList(command, options, file_list, self._root_dir)
|
| -
|
| - # If --reset and --delete_unversioned_trees are specified, remove any
|
| - # untracked files and directories.
|
| - if options.reset and options.delete_unversioned_trees:
|
| - for status in scm.SVN.CaptureStatus(None, self.checkout_path):
|
| - full_path = os.path.join(self.checkout_path, status[1])
|
| - if (status[0][0] == '?'
|
| - and os.path.isdir(full_path)
|
| - and not os.path.islink(full_path)):
|
| - self.Print('_____ removing unversioned directory %s' % status[1])
|
| - gclient_utils.rmtree(full_path)
|
| - return self.Svnversion()
|
| -
|
| - def updatesingle(self, options, args, file_list):
|
| - filename = args.pop()
|
| - if scm.SVN.AssertVersion("1.5")[0]:
|
| - if not os.path.exists(os.path.join(self.checkout_path, '.svn')):
|
| - # Create an empty checkout and then update the one file we want. Future
|
| - # operations will only apply to the one file we checked out.
|
| - command = ["checkout", "--depth", "empty", self.url, self.checkout_path]
|
| - self._Run(command, options, cwd=self._root_dir)
|
| - if os.path.exists(os.path.join(self.checkout_path, filename)):
|
| - os.remove(os.path.join(self.checkout_path, filename))
|
| - command = ["update", filename]
|
| - self._RunAndGetFileList(command, options, file_list)
|
| - # After the initial checkout, we can use update as if it were any other
|
| - # dep.
|
| - self.update(options, args, file_list)
|
| - else:
|
| - # If the installed version of SVN doesn't support --depth, fallback to
|
| - # just exporting the file. This has the downside that revision
|
| - # information is not stored next to the file, so we will have to
|
| - # re-export the file every time we sync.
|
| - if not os.path.exists(self.checkout_path):
|
| - gclient_utils.safe_makedirs(self.checkout_path)
|
| - command = ["export", os.path.join(self.url, filename),
|
| - os.path.join(self.checkout_path, filename)]
|
| - command = self._AddAdditionalUpdateFlags(command, options,
|
| - options.revision)
|
| - self._Run(command, options, cwd=self._root_dir)
|
| -
|
| - def revert(self, options, _args, file_list):
|
| - """Reverts local modifications. Subversion specific.
|
| -
|
| - All reverted files will be appended to file_list, even if Subversion
|
| - doesn't know about them.
|
| - """
|
| - if not os.path.isdir(self.checkout_path):
|
| - if os.path.exists(self.checkout_path):
|
| - gclient_utils.rmtree(self.checkout_path)
|
| - # svn revert won't work if the directory doesn't exist. It needs to
|
| - # checkout instead.
|
| - self.Print('_____ %s is missing, synching instead' % self.relpath)
|
| - # Don't reuse the args.
|
| - return self.update(options, [], file_list)
|
| -
|
| - if not os.path.isdir(os.path.join(self.checkout_path, '.svn')):
|
| - if os.path.isdir(os.path.join(self.checkout_path, '.git')):
|
| - self.Print('________ found .git directory; skipping %s' % self.relpath)
|
| - return
|
| - if os.path.isdir(os.path.join(self.checkout_path, '.hg')):
|
| - self.Print('________ found .hg directory; skipping %s' % self.relpath)
|
| - return
|
| - if not options.force:
|
| - raise gclient_utils.Error('Invalid checkout path, aborting')
|
| - self.Print(
|
| - '\n_____ %s is not a valid svn checkout, synching instead' %
|
| - self.relpath)
|
| - gclient_utils.rmtree(self.checkout_path)
|
| - # Don't reuse the args.
|
| - return self.update(options, [], file_list)
|
| -
|
| - def printcb(file_status):
|
| - if file_list is not None:
|
| - file_list.append(file_status[1])
|
| - if logging.getLogger().isEnabledFor(logging.INFO):
|
| - logging.info('%s%s' % (file_status[0], file_status[1]))
|
| - else:
|
| - self.Print(os.path.join(self.checkout_path, file_status[1]))
|
| - scm.SVN.Revert(self.checkout_path, callback=printcb)
|
| -
|
| - # Revert() may delete the directory altogether.
|
| - if not os.path.isdir(self.checkout_path):
|
| - # Don't reuse the args.
|
| - return self.update(options, [], file_list)
|
| -
|
| - try:
|
| - # svn revert is so broken we don't even use it. Using
|
| - # "svn up --revision BASE" achieve the same effect.
|
| - # file_list will contain duplicates.
|
| - self._RunAndGetFileList(['update', '--revision', 'BASE'], options,
|
| - file_list)
|
| - except OSError, e:
|
| - # Maybe the directory disappeared meanwhile. Do not throw an exception.
|
| - logging.error('Failed to update:\n%s' % str(e))
|
| -
|
| - def revinfo(self, _options, _args, _file_list):
|
| - """Display revision"""
|
| - try:
|
| - return scm.SVN.CaptureRevision(self.checkout_path)
|
| - except (gclient_utils.Error, subprocess2.CalledProcessError):
|
| - return None
|
| -
|
| - def runhooks(self, options, args, file_list):
|
| - self.status(options, args, file_list)
|
| -
|
| - def status(self, options, args, file_list):
|
| - """Display status information."""
|
| - command = ['status'] + args
|
| - if not os.path.isdir(self.checkout_path):
|
| - # svn status won't work if the directory doesn't exist.
|
| - self.Print(('\n________ couldn\'t run \'%s\' in \'%s\':\n'
|
| - 'The directory does not exist.') %
|
| - (' '.join(command), self.checkout_path))
|
| - # There's no file list to retrieve.
|
| - else:
|
| - self._RunAndGetFileList(command, options, file_list)
|
| -
|
| - def GetUsableRev(self, rev, _options):
|
| - """Verifies the validity of the revision for this repository."""
|
| - if not scm.SVN.IsValidRevision(url='%s@%s' % (self.url, rev)):
|
| - raise NoUsableRevError(
|
| - ( '%s isn\'t a valid revision. Please check that your safesync_url is\n'
|
| - 'correct.') % rev)
|
| - return rev
|
| -
|
| - def FullUrlForRelativeUrl(self, url):
|
| - # Find the forth '/' and strip from there. A bit hackish.
|
| - return '/'.join(self.url.split('/')[:4]) + url
|
| -
|
| - def _Run(self, args, options, **kwargs):
|
| - """Runs a commands that goes to stdout."""
|
| - kwargs.setdefault('cwd', self.checkout_path)
|
| - gclient_utils.CheckCallAndFilterAndHeader(['svn'] + args,
|
| - always=options.verbose, **kwargs)
|
| -
|
| - def Svnversion(self):
|
| - """Runs the lowest checked out revision in the current project."""
|
| - info = scm.SVN.CaptureLocalInfo([], os.path.join(self.checkout_path, '.'))
|
| - return info['Revision']
|
| -
|
| - def _RunAndGetFileList(self, args, options, file_list, cwd=None):
|
| - """Runs a commands that goes to stdout and grabs the file listed."""
|
| - cwd = cwd or self.checkout_path
|
| - scm.SVN.RunAndGetFileList(
|
| - options.verbose,
|
| - args + ['--ignore-externals'],
|
| - cwd=cwd,
|
| - file_list=file_list)
|
| -
|
| - @staticmethod
|
| - def _AddAdditionalUpdateFlags(command, options, revision):
|
| - """Add additional flags to command depending on what options are set.
|
| - command should be a list of strings that represents an svn command.
|
| -
|
| - This method returns a new list to be used as a command."""
|
| - new_command = command[:]
|
| - if revision:
|
| - new_command.extend(['--revision', str(revision).strip()])
|
| - # We don't want interaction when jobs are used.
|
| - if options.jobs > 1:
|
| - new_command.append('--non-interactive')
|
| - # --force was added to 'svn update' in svn 1.5.
|
| - # --accept was added to 'svn update' in svn 1.6.
|
| - if not scm.SVN.AssertVersion('1.5')[0]:
|
| - return new_command
|
| -
|
| - # It's annoying to have it block in the middle of a sync, just sensible
|
| - # defaults.
|
| - if options.force:
|
| - new_command.append('--force')
|
| - if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
|
| - new_command.extend(('--accept', 'theirs-conflict'))
|
| - elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
|
| - new_command.extend(('--accept', 'postpone'))
|
| - return new_command
|
|
|