Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(84)

Side by Side Diff: gclient_scm.py

Issue 183283003: Another attempt: gclient: delete mismatching checkouts (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/depot_tools
Patch Set: Fix for unmanaged git-svn, remove commented lines Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | scm.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """Gclient-specific SCM-specific operations.""" 5 """Gclient-specific SCM-specific operations."""
6 6
7 import logging 7 import logging
8 import os 8 import os
9 import posixpath 9 import posixpath
10 import re 10 import re
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 # For compatibility with old naming, translate 'origin' to 'refs/heads' 293 # For compatibility with old naming, translate 'origin' to 'refs/heads'
294 revision = revision.replace(self.remote + '/', 'refs/heads/') 294 revision = revision.replace(self.remote + '/', 'refs/heads/')
295 rev_type = "branch" 295 rev_type = "branch"
296 else: 296 else:
297 # hash is also a tag, only make a distinction at checkout 297 # hash is also a tag, only make a distinction at checkout
298 rev_type = "hash" 298 rev_type = "hash"
299 299
300 if (not os.path.exists(self.checkout_path) or 300 if (not os.path.exists(self.checkout_path) or
301 (os.path.isdir(self.checkout_path) and 301 (os.path.isdir(self.checkout_path) and
302 not os.path.exists(os.path.join(self.checkout_path, '.git')))): 302 not os.path.exists(os.path.join(self.checkout_path, '.git')))):
303 if (os.path.isdir(self.checkout_path) and
304 not os.path.exists(os.path.join(self.checkout_path, '.git'))):
305 if options.force:
306 # Delete and re-sync.
307 print('_____ Conflicting directory found in %s. Removing.'
308 % self.checkout_path)
309 gclient_utils.rmtree(self.checkout_path)
310 else:
311 raise gclient_utils.Error('\n____ %s%s\n'
312 '\tPath is not a git repo. No .git dir.\n'
313 '\tTo resolve:\n'
314 '\t\trm -rf %s\n'
315 '\tAnd run gclient sync again\n'
316 '\tOr run with --force\n'
317 % (self.relpath, rev_str, self.relpath))
303 self._Clone(revision, url, options) 318 self._Clone(revision, url, options)
304 self.UpdateSubmoduleConfig() 319 self.UpdateSubmoduleConfig()
305 if file_list is not None: 320 if file_list is not None:
306 files = self._Capture(['ls-files']).splitlines() 321 files = self._Capture(['ls-files']).splitlines()
307 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) 322 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
308 if not verbose: 323 if not verbose:
309 # Make the output a little prettier. It's nice to have some whitespace 324 # Make the output a little prettier. It's nice to have some whitespace
310 # between projects when cloning. 325 # between projects when cloning.
311 print('') 326 print('')
312 return self._Capture(['rev-parse', '--verify', 'HEAD']) 327 return self._Capture(['rev-parse', '--verify', 'HEAD'])
313 328
314 if not managed: 329 if not managed:
315 self._UpdateBranchHeads(options, fetch=False) 330 self._UpdateBranchHeads(options, fetch=False)
316 self.UpdateSubmoduleConfig() 331 self.UpdateSubmoduleConfig()
317 print ('________ unmanaged solution; skipping %s' % self.relpath) 332 print ('________ unmanaged solution; skipping %s' % self.relpath)
318 return self._Capture(['rev-parse', '--verify', 'HEAD']) 333 return self._Capture(['rev-parse', '--verify', 'HEAD'])
319 334
320 if not os.path.exists(os.path.join(self.checkout_path, '.git')):
321 raise gclient_utils.Error('\n____ %s%s\n'
322 '\tPath is not a git repo. No .git dir.\n'
323 '\tTo resolve:\n'
324 '\t\trm -rf %s\n'
325 '\tAnd run gclient sync again\n'
326 % (self.relpath, rev_str, self.relpath))
327
328 # See if the url has changed (the unittests use git://foo for the url, let 335 # See if the url has changed (the unittests use git://foo for the url, let
329 # that through). 336 # that through).
330 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) 337 current_url = self._Capture(['config', 'remote.%s.url' % self.remote])
331 return_early = False 338 return_early = False
332 # TODO(maruel): Delete url != 'git://foo' since it's just to make the 339 # TODO(maruel): Delete url != 'git://foo' since it's just to make the
333 # unit test pass. (and update the comment above) 340 # unit test pass. (and update the comment above)
334 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. 341 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set.
335 # This allows devs to use experimental repos which have a different url 342 # This allows devs to use experimental repos which have a different url
336 # but whose branch(s) are the same as official repos. 343 # but whose branch(s) are the same as official repos.
337 if (current_url != url and 344 if (current_url.rstrip('/') != url.rstrip('/') and
338 url != 'git://foo' and 345 url != 'git://foo' and
339 subprocess2.capture( 346 subprocess2.capture(
340 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], 347 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote],
341 cwd=self.checkout_path).strip() != 'False'): 348 cwd=self.checkout_path).strip() != 'False'):
342 print('_____ switching %s to a new upstream' % self.relpath) 349 print('_____ switching %s to a new upstream' % self.relpath)
343 # Make sure it's clean 350 # Make sure it's clean
344 self._CheckClean(rev_str) 351 self._CheckClean(rev_str)
345 # Switch over to the new upstream 352 # Switch over to the new upstream
346 self._Run(['remote', 'set-url', self.remote, url], options) 353 self._Run(['remote', 'set-url', self.remote, url], options)
347 self._FetchAndReset(revision, file_list, options) 354 self._FetchAndReset(revision, file_list, options)
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 filter_fn=SvnDiffFilterer(self.relpath).Filter) 999 filter_fn=SvnDiffFilterer(self.relpath).Filter)
993 1000
994 def update(self, options, args, file_list): 1001 def update(self, options, args, file_list):
995 """Runs svn to update or transparently checkout the working copy. 1002 """Runs svn to update or transparently checkout the working copy.
996 1003
997 All updated files will be appended to file_list. 1004 All updated files will be appended to file_list.
998 1005
999 Raises: 1006 Raises:
1000 Error: if can't get URL for relative path. 1007 Error: if can't get URL for relative path.
1001 """ 1008 """
1002 # Only update if git or hg is not controlling the directory. 1009 # Only update if hg is not controlling the directory.
1003 git_path = os.path.join(self.checkout_path, '.git')
1004 if os.path.exists(git_path):
1005 print('________ found .git directory; skipping %s' % self.relpath)
1006 return
1007
1008 hg_path = os.path.join(self.checkout_path, '.hg') 1010 hg_path = os.path.join(self.checkout_path, '.hg')
1009 if os.path.exists(hg_path): 1011 if os.path.exists(hg_path):
1010 print('________ found .hg directory; skipping %s' % self.relpath) 1012 print('________ found .hg directory; skipping %s' % self.relpath)
1011 return 1013 return
1012 1014
1013 if args: 1015 if args:
1014 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) 1016 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))
1015 1017
1016 # revision is the revision to match. It is None if no revision is specified, 1018 # revision is the revision to match. It is None if no revision is specified,
1017 # i.e. the 'deps ain't pinned'. 1019 # i.e. the 'deps ain't pinned'.
(...skipping 10 matching lines...) Expand all
1028 # Reconstruct the url. 1030 # Reconstruct the url.
1029 url = '%s@%s' % (url, revision) 1031 url = '%s@%s' % (url, revision)
1030 rev_str = ' at %s' % revision 1032 rev_str = ' at %s' % revision
1031 else: 1033 else:
1032 managed = False 1034 managed = False
1033 revision = None 1035 revision = None
1034 else: 1036 else:
1035 forced_revision = False 1037 forced_revision = False
1036 rev_str = '' 1038 rev_str = ''
1037 1039
1040 exists = os.path.exists(self.checkout_path)
1041 if exists and managed:
1042 # Git is only okay if it's a git-svn checkout of the right repo.
1043 if scm.GIT.IsGitSvn(self.checkout_path):
1044 remote_url = scm.GIT.Capture(['config', '--local', '--get',
1045 'svn-remote.svn.url'],
1046 cwd=self.checkout_path).rstrip()
1047 if remote_url.rstrip('/') == base_url.rstrip('/'):
1048 print('\n_____ %s looks like a git-svn checkout. Skipping.'
1049 % self.relpath)
1050 return # TODO(borenet): Get the svn revision number?
1051
1038 # Get the existing scm url and the revision number of the current checkout. 1052 # Get the existing scm url and the revision number of the current checkout.
1039 exists = os.path.exists(self.checkout_path)
1040 if exists and managed: 1053 if exists and managed:
1041 try: 1054 try:
1042 from_info = scm.SVN.CaptureLocalInfo( 1055 from_info = scm.SVN.CaptureLocalInfo(
1043 [], os.path.join(self.checkout_path, '.')) 1056 [], os.path.join(self.checkout_path, '.'))
1044 except (gclient_utils.Error, subprocess2.CalledProcessError): 1057 except (gclient_utils.Error, subprocess2.CalledProcessError):
1045 if options.reset and options.delete_unversioned_trees: 1058 if (options.force or
1059 (options.reset and options.delete_unversioned_trees)):
1046 print 'Removing troublesome path %s' % self.checkout_path 1060 print 'Removing troublesome path %s' % self.checkout_path
1047 gclient_utils.rmtree(self.checkout_path) 1061 gclient_utils.rmtree(self.checkout_path)
1048 exists = False 1062 exists = False
1049 else: 1063 else:
1050 msg = ('Can\'t update/checkout %s if an unversioned directory is ' 1064 msg = ('Can\'t update/checkout %s if an unversioned directory is '
1051 'present. Delete the directory and try again.') 1065 'present. Delete the directory and try again.')
1052 raise gclient_utils.Error(msg % self.checkout_path) 1066 raise gclient_utils.Error(msg % self.checkout_path)
1053 1067
1054 BASE_URLS = { 1068 BASE_URLS = {
1055 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/', 1069 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/',
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1122 1136
1123 gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path)) 1137 gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path))
1124 # We need to checkout. 1138 # We need to checkout.
1125 command = ['checkout', url, self.checkout_path] 1139 command = ['checkout', url, self.checkout_path]
1126 command = self._AddAdditionalUpdateFlags(command, options, revision) 1140 command = self._AddAdditionalUpdateFlags(command, options, revision)
1127 self._RunAndGetFileList(command, options, file_list, self._root_dir) 1141 self._RunAndGetFileList(command, options, file_list, self._root_dir)
1128 return self.Svnversion() 1142 return self.Svnversion()
1129 1143
1130 if not managed: 1144 if not managed:
1131 print ('________ unmanaged solution; skipping %s' % self.relpath) 1145 print ('________ unmanaged solution; skipping %s' % self.relpath)
1132 return self.Svnversion() 1146 if not scm.GIT.IsGitSvn(self.checkout_path):
1147 return self.Svnversion()
1148 return
1133 1149
1134 if 'URL' not in from_info: 1150 if 'URL' not in from_info:
1135 raise gclient_utils.Error( 1151 raise gclient_utils.Error(
1136 ('gclient is confused. Couldn\'t get the url for %s.\n' 1152 ('gclient is confused. Couldn\'t get the url for %s.\n'
1137 'Try using @unmanaged.\n%s') % ( 1153 'Try using @unmanaged.\n%s') % (
1138 self.checkout_path, from_info)) 1154 self.checkout_path, from_info))
1139 1155
1140 # Look for locked directories. 1156 # Look for locked directories.
1141 dir_info = scm.SVN.CaptureStatus( 1157 dir_info = scm.SVN.CaptureStatus(
1142 None, os.path.join(self.checkout_path, '.')) 1158 None, os.path.join(self.checkout_path, '.'))
(...skipping 22 matching lines...) Expand all
1165 if d[0][0] == '!': 1181 if d[0][0] == '!':
1166 print 'You can pass --force to enable automatic removal.' 1182 print 'You can pass --force to enable automatic removal.'
1167 raise e 1183 raise e
1168 1184
1169 # Retrieve the current HEAD version because svn is slow at null updates. 1185 # Retrieve the current HEAD version because svn is slow at null updates.
1170 if options.manually_grab_svn_rev and not revision: 1186 if options.manually_grab_svn_rev and not revision:
1171 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) 1187 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL'])
1172 revision = str(from_info_live['Revision']) 1188 revision = str(from_info_live['Revision'])
1173 rev_str = ' at %s' % revision 1189 rev_str = ' at %s' % revision
1174 1190
1175 if from_info['URL'] != base_url: 1191 if from_info['URL'].rstrip('/') != base_url.rstrip('/'):
1176 # The repository url changed, need to switch. 1192 # The repository url changed, need to switch.
1177 try: 1193 try:
1178 to_info = scm.SVN.CaptureRemoteInfo(url) 1194 to_info = scm.SVN.CaptureRemoteInfo(url)
1179 except (gclient_utils.Error, subprocess2.CalledProcessError): 1195 except (gclient_utils.Error, subprocess2.CalledProcessError):
1180 # The url is invalid or the server is not accessible, it's safer to bail 1196 # The url is invalid or the server is not accessible, it's safer to bail
1181 # out right now. 1197 # out right now.
1182 raise gclient_utils.Error('This url is unreachable: %s' % url) 1198 raise gclient_utils.Error('This url is unreachable: %s' % url)
1183 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) 1199 can_switch = ((from_info['Repository Root'] != to_info['Repository Root'])
1184 and (from_info['UUID'] == to_info['UUID'])) 1200 and (from_info['UUID'] == to_info['UUID']))
1185 if can_switch: 1201 if can_switch:
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 new_command.append('--force') 1417 new_command.append('--force')
1402 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1418 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1403 new_command.extend(('--accept', 'theirs-conflict')) 1419 new_command.extend(('--accept', 'theirs-conflict'))
1404 elif options.manually_grab_svn_rev: 1420 elif options.manually_grab_svn_rev:
1405 new_command.append('--force') 1421 new_command.append('--force')
1406 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1422 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1407 new_command.extend(('--accept', 'postpone')) 1423 new_command.extend(('--accept', 'postpone'))
1408 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1424 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1409 new_command.extend(('--accept', 'postpone')) 1425 new_command.extend(('--accept', 'postpone'))
1410 return new_command 1426 return new_command
OLDNEW
« no previous file with comments | « no previous file | scm.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698