Index: gclient_scm.py |
diff --git a/gclient_scm.py b/gclient_scm.py |
index 0389f466203b86413e0253ab9095d4cd422fe8ad..5ba1cd619c67ed17e75c45ff8b98462d86d036d0 100644 |
--- a/gclient_scm.py |
+++ b/gclient_scm.py |
@@ -302,55 +302,66 @@ class GitWrapper(SCMWrapper): |
# hash is also a tag, only make a distinction at checkout |
rev_type = "hash" |
- 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: |
- files = self._Capture(['ls-files']).splitlines() |
- file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
- if not verbose: |
- # Make the output a little prettier. It's nice to have some whitespace |
- # between projects when cloning. |
- 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)) |
+ 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). |
- 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 |
+ 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): |
+ self._Clone(revision, url, options) |
+ self.UpdateSubmoduleConfig() |
+ if file_list is not None: |
+ files = self._Capture(['ls-files']).splitlines() |
+ file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
+ if not verbose: |
+ # Make the output a little prettier. It's nice to have some whitespace |
+ # between projects when cloning. |
+ print('') |
+ return self._Capture(['rev-parse', '--verify', 'HEAD']) |
# Need to do this in the normal path as well as in the post-remote-switch |
# path. |
@@ -625,7 +636,7 @@ class GitWrapper(SCMWrapper): |
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): |
+ if scm.GIT.IsGitSvn(self.checkout_path): |
local_head = scm.GIT.GetGitSvnHeadRev(cwd=self.checkout_path) |
if not local_head or local_head < int(rev): |
try: |
@@ -1104,17 +1115,6 @@ class SVNWrapper(SCMWrapper): |
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)) |
@@ -1140,21 +1140,86 @@ class SVNWrapper(SCMWrapper): |
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) |
- if exists and managed: |
+ 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? |
+ |
try: |
from_info = scm.SVN.CaptureLocalInfo( |
[], os.path.join(self.checkout_path, '.')) |
except (gclient_utils.Error, subprocess2.CalledProcessError): |
- 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) |
+ 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) |
BASE_URLS = { |
'/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/', |
@@ -1232,10 +1297,6 @@ class SVNWrapper(SCMWrapper): |
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' |
@@ -1277,53 +1338,6 @@ class SVNWrapper(SCMWrapper): |
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: |
@@ -1393,9 +1407,6 @@ class SVNWrapper(SCMWrapper): |
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( |