Skip to content

Commit

Permalink
Revert "Re-re-land gclient deletion of mismatching checkouts again"
Browse files Browse the repository at this point in the history
This reverts commit 6ff5448.

'fetch --nohooks chromium' is broken with this change.

BUG=

Review URL: https://codereview.chromium.org/177003023

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@253640 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
szager@chromium.org committed Feb 26, 2014
1 parent 6ff5448 commit 6c2b49d
Show file tree
Hide file tree
Showing 7 changed files with 167 additions and 321 deletions.
239 changes: 114 additions & 125 deletions gclient_scm.py
Expand Up @@ -302,56 +302,9 @@ def update(self, options, args, file_list):
# hash is also a tag, only make a distinction at checkout
rev_type = "hash"

if not managed:
self._UpdateBranchHeads(options, fetch=False)
self.UpdateSubmoduleConfig()
print ('________ unmanaged solution; skipping %s' % self.relpath)
return self._Capture(['rev-parse', '--verify', 'HEAD'])

needs_delete = False
exists = os.path.exists(self.checkout_path)
if exists and not os.path.exists(os.path.join(self.checkout_path, '.git')):
needs_delete = True

# See if the url has changed (the unittests use git://foo for the url, let
# that through).
return_early = False
if exists and not needs_delete:
current_url = self._Capture(['config', 'remote.%s.url' % self.remote])
# TODO(maruel): Delete url != 'git://foo' since it's just to make the
# unit test pass. (and update the comment above)
# Skip url auto-correction if remote.origin.gclient-auto-fix-url is set.
# This allows devs to use experimental repos which have a different url
# but whose branch(s) are the same as official repos.
if (current_url != url and url != 'git://foo'):
auto_fix = 'True'
try:
auto_fix = self._Capture(
['config', 'remote.%s.gclient-auto-fix-url' % self.remote],
cwd=self.checkout_path).strip()
except subprocess2.CalledProcessError:
pass
if auto_fix in ('1', 'true', 'True', 'yes', 'Yes', 'y', 'Y'):
print('_____ switching %s to a new upstream' % self.relpath)
# Make sure it's clean
self._CheckClean(rev_str)
# Switch over to the new upstream
self._Run(['remote', 'set-url', self.remote, url], options)
self._FetchAndReset(revision, file_list, options)
return_early = True

if (needs_delete and
gclient_utils.enable_deletion_of_conflicting_checkouts()):
if options.force:
print('Conflicting directory found in %s. Removing.'
% self.checkout_path)
gclient_utils.rmtree(self.checkout_path)
else:
raise gclient_utils.Error('Conflicting directory found in %s. Please '
'delete it or run with --force.'
% self.checkout_path)

if not os.path.exists(self.checkout_path):
if (not os.path.exists(self.checkout_path) or
(os.path.isdir(self.checkout_path) and
not os.path.exists(os.path.join(self.checkout_path, '.git')))):
self._Clone(revision, url, options)
self.UpdateSubmoduleConfig()
if file_list is not None:
Expand All @@ -363,6 +316,42 @@ def update(self, options, args, file_list):
print('')
return self._Capture(['rev-parse', '--verify', 'HEAD'])

if not managed:
self._UpdateBranchHeads(options, fetch=False)
self.UpdateSubmoduleConfig()
print ('________ unmanaged solution; skipping %s' % self.relpath)
return self._Capture(['rev-parse', '--verify', 'HEAD'])

if not os.path.exists(os.path.join(self.checkout_path, '.git')):
raise gclient_utils.Error('\n____ %s%s\n'
'\tPath is not a git repo. No .git dir.\n'
'\tTo resolve:\n'
'\t\trm -rf %s\n'
'\tAnd run gclient sync again\n'
% (self.relpath, rev_str, self.relpath))

# See if the url has changed (the unittests use git://foo for the url, let
# that through).
current_url = self._Capture(['config', 'remote.%s.url' % self.remote])
return_early = False
# TODO(maruel): Delete url != 'git://foo' since it's just to make the
# unit test pass. (and update the comment above)
# Skip url auto-correction if remote.origin.gclient-auto-fix-url is set.
# This allows devs to use experimental repos which have a different url
# but whose branch(s) are the same as official repos.
if (current_url != url and
url != 'git://foo' and
subprocess2.capture(
['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote],
cwd=self.checkout_path).strip() != 'False'):
print('_____ switching %s to a new upstream' % self.relpath)
# Make sure it's clean
self._CheckClean(rev_str)
# Switch over to the new upstream
self._Run(['remote', 'set-url', self.remote, url], options)
self._FetchAndReset(revision, file_list, options)
return_early = True

# Need to do this in the normal path as well as in the post-remote-switch
# path.
self._PossiblySwitchCache(url, options)
Expand Down Expand Up @@ -636,7 +625,7 @@ def GetUsableRev(self, rev, options):
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(self.checkout_path):
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:
Expand Down Expand Up @@ -1115,6 +1104,17 @@ def update(self, options, args, file_list):
Raises:
Error: if can't get URL for relative path.
"""
# Only update if git or hg is not controlling the directory.
git_path = os.path.join(self.checkout_path, '.git')
if os.path.exists(git_path):
print('________ found .git directory; skipping %s' % self.relpath)
return

hg_path = os.path.join(self.checkout_path, '.hg')
if os.path.exists(hg_path):
print('________ found .hg directory; skipping %s' % self.relpath)
return

if args:
raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))

Expand All @@ -1140,86 +1140,21 @@ def update(self, options, args, file_list):
forced_revision = False
rev_str = ''

if not managed:
print ('________ unmanaged solution; skipping %s' % self.relpath)
return self.Svnversion()

# Get the existing scm url and the revision number of the current checkout.
exists = os.path.exists(self.checkout_path)
needs_delete = False
from_info = None

if exists:
# If there's a git-svn checkout, verify that the svn-remote is correct.
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 != base_url:
needs_delete = True
else:
print('\n_____ %s looks like a git-svn checkout. Skipping.'
% self.relpath)
return # TODO(borenet): Get the svn revision number?

if exists and managed:
try:
from_info = scm.SVN.CaptureLocalInfo(
[], os.path.join(self.checkout_path, '.'))
except (gclient_utils.Error, subprocess2.CalledProcessError):
if gclient_utils.enable_deletion_of_conflicting_checkouts():
needs_delete = True
else: # TODO(borenet): Remove this once we can get rid of the guard.
if options.reset and options.delete_unversioned_trees:
print 'Removing troublesome path %s' % self.checkout_path
gclient_utils.rmtree(self.checkout_path)
exists = False
else:
msg = ('Can\'t update/checkout %s if an unversioned directory is '
'present. Delete the directory and try again.')
raise gclient_utils.Error(msg % self.checkout_path)

# Switch the checkout if necessary.
if not needs_delete and from_info and from_info['URL'] != base_url:
# 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:
print('\n_____ 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:
needs_delete = True

if (needs_delete and
gclient_utils.enable_deletion_of_conflicting_checkouts()):
if options.force:
gclient_utils.rmtree(self.checkout_path)
exists = False
else:
raise gclient_utils.Error('Conflicting directory found in %s. Please '
'delete it or run with --force.'
% self.checkout_path)
if options.reset and options.delete_unversioned_trees:
print 'Removing troublesome path %s' % self.checkout_path
gclient_utils.rmtree(self.checkout_path)
exists = False
else:
msg = ('Can\'t update/checkout %s if an unversioned directory is '
'present. Delete the directory and try again.')
raise gclient_utils.Error(msg % self.checkout_path)

BASE_URLS = {
'/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/',
Expand Down Expand Up @@ -1297,6 +1232,10 @@ def update(self, options, args, file_list):
self._RunAndGetFileList(command, options, file_list, self._root_dir)
return self.Svnversion()

if not managed:
print ('________ unmanaged solution; skipping %s' % self.relpath)
return self.Svnversion()

if 'URL' not in from_info:
raise gclient_utils.Error(
('gclient is confused. Couldn\'t get the url for %s.\n'
Expand Down Expand Up @@ -1338,6 +1277,53 @@ def update(self, options, args, file_list):
revision = str(from_info_live['Revision'])
rev_str = ' at %s' % revision

if from_info['URL'] != base_url:
# 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:
print('\n_____ 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.
print('\n_____ 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:
Expand Down Expand Up @@ -1407,6 +1393,9 @@ def revert(self, options, _args, file_list):
if os.path.isdir(os.path.join(self.checkout_path, '.git')):
print('________ found .git directory; skipping %s' % self.relpath)
return
if os.path.isdir(os.path.join(self.checkout_path, '.hg')):
print('________ found .hg directory; skipping %s' % self.relpath)
return
if not options.force:
raise gclient_utils.Error('Invalid checkout path, aborting')
print(
Expand Down
15 changes: 0 additions & 15 deletions gclient_utils.py
Expand Up @@ -10,7 +10,6 @@
import pipes
import Queue
import re
import socket
import stat
import subprocess
import sys
Expand All @@ -26,20 +25,6 @@
RETRY_INITIAL_SLEEP = 0.5


def enable_deletion_of_conflicting_checkouts():
"""Determines whether to enable new checkout deletion behavior.
Initially, enables the experimental functionality on a small set of
bots.
"""
# TODO(borenet): Remove this hack as soon as we've verified that it
# doesn't cause the bots to break.
if not os.environ.get('CHROME_HEADLESS'):
return False
return socket.gethostname() in ('vm859-m1', 'BUILD1-M1',
'vm630-m1.golo.chromium.org')


class Error(Exception):
"""gclient exception class."""
def __init__(self, msg, *args, **kwargs):
Expand Down
9 changes: 3 additions & 6 deletions scm.py
Expand Up @@ -166,15 +166,12 @@ def GetBranch(cwd):
return GIT.ShortBranchName(GIT.GetBranchRef(cwd))

@staticmethod
def IsGitSvn(checkout_root):
def IsGitSvn(cwd):
"""Returns true if this repo looks like it's using git-svn."""
# A git-svn checkout has a .git directory.
if not os.path.exists(os.path.join(checkout_root, '.git')):
return False
# If you have any "svn-remote.*" config keys, we think you're using svn.
try:
GIT.Capture(['config', '--local', '--get-regexp', r'^svn-remote\.'],
cwd=checkout_root)
cwd=cwd)
return True
except subprocess2.CalledProcessError:
return False
Expand Down Expand Up @@ -411,7 +408,7 @@ def ParseGitSvnSha1(output):
@staticmethod
def GetSha1ForSvnRev(cwd, rev):
"""Returns a corresponding git sha1 for a SVN revision."""
if not GIT.IsGitSvn(cwd):
if not GIT.IsGitSvn(cwd=cwd):
return None
try:
output = GIT.Capture(['svn', 'find-rev', 'r' + str(rev)], cwd=cwd)
Expand Down

0 comments on commit 6c2b49d

Please sign in to comment.