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

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: rebase 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 279 matching lines...) Expand 10 before | Expand all | Expand 10 after
290 if revision.startswith('refs/'): 290 if revision.startswith('refs/'):
291 rev_type = "branch" 291 rev_type = "branch"
292 elif revision.startswith(self.remote + '/'): 292 elif revision.startswith(self.remote + '/'):
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)):
301 (os.path.isdir(self.checkout_path) and
302 not os.path.exists(os.path.join(self.checkout_path, '.git')))):
303 self._Clone(revision, url, options) 301 self._Clone(revision, url, options)
304 self.UpdateSubmoduleConfig() 302 self.UpdateSubmoduleConfig()
305 if file_list is not None: 303 if file_list is not None:
306 files = self._Capture(['ls-files']).splitlines() 304 files = self._Capture(['ls-files']).splitlines()
307 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) 305 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
308 if not verbose: 306 if not verbose:
309 # Make the output a little prettier. It's nice to have some whitespace 307 # Make the output a little prettier. It's nice to have some whitespace
310 # between projects when cloning. 308 # between projects when cloning.
311 print('') 309 print('')
312 return self._Capture(['rev-parse', '--verify', 'HEAD']) 310 return self._Capture(['rev-parse', '--verify', 'HEAD'])
313 311
314 if not managed: 312 if not managed:
315 self._UpdateBranchHeads(options, fetch=False) 313 self._UpdateBranchHeads(options, fetch=False)
316 self.UpdateSubmoduleConfig() 314 self.UpdateSubmoduleConfig()
317 print ('________ unmanaged solution; skipping %s' % self.relpath) 315 print ('________ unmanaged solution; skipping %s' % self.relpath)
318 return self._Capture(['rev-parse', '--verify', 'HEAD']) 316 return self._Capture(['rev-parse', '--verify', 'HEAD'])
319 317
320 if not os.path.exists(os.path.join(self.checkout_path, '.git')): 318 if not os.path.exists(os.path.join(self.checkout_path, '.git')):
321 raise gclient_utils.Error('\n____ %s%s\n' 319 if options.force:
322 '\tPath is not a git repo. No .git dir.\n' 320 # Delete and re-sync.
323 '\tTo resolve:\n' 321 print('_____ Conflicting directory found in %s. Removing.'
324 '\t\trm -rf %s\n' 322 % self.checkout_path)
325 '\tAnd run gclient sync again\n' 323 gclient_utils.rmtree(self.checkout_path)
326 % (self.relpath, rev_str, self.relpath)) 324 self._Clone(revision, url, options)
325 self.UpdateSubmoduleConfig()
326 if file_list is not None:
327 files = self._Capture(['ls-files']).splitlines()
328 file_list.extend([os.path.join(self.checkout_path, f) for f in files])
329 if not verbose:
330 # Make the output a little prettier. It's nice to have some whitespace
331 # between projects when cloning.
332 print('')
333 return self._Capture(['rev-parse', '--verify', 'HEAD'])
iannucci 2014/03/05 22:04:07 I really dislike this pattern in gclient (although
borenet 2014/03/06 14:27:19 Done. It seems like this whole block is not needed
borenet 2014/03/06 18:04:49 I'm a little concerned about adding this logic abo
iannucci 2014/03/07 20:31:19 Hm... Couldn't we just check the managed boolean a
borenet 2014/03/07 21:50:12 I think you're right, but I've been surprised befo
334 else:
335 raise gclient_utils.Error('\n____ %s%s\n'
336 '\tPath is not a git repo. No .git dir.\n'
337 '\tTo resolve:\n'
338 '\t\trm -rf %s\n'
339 '\tAnd run gclient sync again\n'
340 '\tOr run with --force\n'
341 % (self.relpath, rev_str, self.relpath))
327 342
328 # See if the url has changed (the unittests use git://foo for the url, let 343 # See if the url has changed (the unittests use git://foo for the url, let
329 # that through). 344 # that through).
330 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) 345 current_url = self._Capture(['config', 'remote.%s.url' % self.remote])
331 return_early = False 346 return_early = False
332 # TODO(maruel): Delete url != 'git://foo' since it's just to make the 347 # TODO(maruel): Delete url != 'git://foo' since it's just to make the
333 # unit test pass. (and update the comment above) 348 # unit test pass. (and update the comment above)
334 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. 349 # 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 350 # This allows devs to use experimental repos which have a different url
336 # but whose branch(s) are the same as official repos. 351 # but whose branch(s) are the same as official repos.
337 if (current_url != url and 352 if (current_url.rstrip('/') != url.rstrip('/') and
338 url != 'git://foo' and 353 url != 'git://foo' and
339 subprocess2.capture( 354 subprocess2.capture(
340 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], 355 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote],
341 cwd=self.checkout_path).strip() != 'False'): 356 cwd=self.checkout_path).strip() != 'False'):
342 print('_____ switching %s to a new upstream' % self.relpath) 357 print('_____ switching %s to a new upstream' % self.relpath)
343 # Make sure it's clean 358 # Make sure it's clean
344 self._CheckClean(rev_str) 359 self._CheckClean(rev_str)
345 # Switch over to the new upstream 360 # Switch over to the new upstream
346 self._Run(['remote', 'set-url', self.remote, url], options) 361 self._Run(['remote', 'set-url', self.remote, url], options)
347 self._FetchAndReset(revision, file_list, options) 362 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) 1007 filter_fn=SvnDiffFilterer(self.relpath).Filter)
993 1008
994 def update(self, options, args, file_list): 1009 def update(self, options, args, file_list):
995 """Runs svn to update or transparently checkout the working copy. 1010 """Runs svn to update or transparently checkout the working copy.
996 1011
997 All updated files will be appended to file_list. 1012 All updated files will be appended to file_list.
998 1013
999 Raises: 1014 Raises:
1000 Error: if can't get URL for relative path. 1015 Error: if can't get URL for relative path.
1001 """ 1016 """
1002 # Only update if git or hg is not controlling the directory. 1017 # 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') 1018 hg_path = os.path.join(self.checkout_path, '.hg')
1009 if os.path.exists(hg_path): 1019 if os.path.exists(hg_path):
1010 print('________ found .hg directory; skipping %s' % self.relpath) 1020 print('________ found .hg directory; skipping %s' % self.relpath)
1011 return 1021 return
1012 1022
1013 if args: 1023 if args:
1014 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) 1024 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args))
1015 1025
1016 # revision is the revision to match. It is None if no revision is specified, 1026 # revision is the revision to match. It is None if no revision is specified,
1017 # i.e. the 'deps ain't pinned'. 1027 # i.e. the 'deps ain't pinned'.
(...skipping 10 matching lines...) Expand all
1028 # Reconstruct the url. 1038 # Reconstruct the url.
1029 url = '%s@%s' % (url, revision) 1039 url = '%s@%s' % (url, revision)
1030 rev_str = ' at %s' % revision 1040 rev_str = ' at %s' % revision
1031 else: 1041 else:
1032 managed = False 1042 managed = False
1033 revision = None 1043 revision = None
1034 else: 1044 else:
1035 forced_revision = False 1045 forced_revision = False
1036 rev_str = '' 1046 rev_str = ''
1037 1047
1048 exists = os.path.exists(self.checkout_path)
1049 if exists and managed:
1050 # Git is only okay if it's a git-svn checkout of the right repo.
1051 if scm.GIT.IsGitSvn(self.checkout_path):
1052 remote_url = scm.GIT.Capture(['config', '--local', '--get',
1053 'svn-remote.svn.url'],
1054 cwd=self.checkout_path).rstrip()
1055 if remote_url.rstrip('/') == base_url.rstrip('/'):
1056 print('\n_____ %s looks like a git-svn checkout. Skipping.'
1057 % self.relpath)
1058 return # TODO(borenet): Get the svn revision number?
iannucci 2014/03/07 20:31:19 Can you try this scenario with --json-output? It
borenet 2014/03/07 21:50:12 I tried this with a checkout of skia: $ git svn cl
1059
1038 # Get the existing scm url and the revision number of the current checkout. 1060 # 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: 1061 if exists and managed:
1041 try: 1062 try:
1042 from_info = scm.SVN.CaptureLocalInfo( 1063 from_info = scm.SVN.CaptureLocalInfo(
1043 [], os.path.join(self.checkout_path, '.')) 1064 [], os.path.join(self.checkout_path, '.'))
1044 except (gclient_utils.Error, subprocess2.CalledProcessError): 1065 except (gclient_utils.Error, subprocess2.CalledProcessError):
1045 if options.reset and options.delete_unversioned_trees: 1066 if (options.force or
1067 (options.reset and options.delete_unversioned_trees)):
1046 print 'Removing troublesome path %s' % self.checkout_path 1068 print 'Removing troublesome path %s' % self.checkout_path
1047 gclient_utils.rmtree(self.checkout_path) 1069 gclient_utils.rmtree(self.checkout_path)
1048 exists = False 1070 exists = False
1049 else: 1071 else:
1050 msg = ('Can\'t update/checkout %s if an unversioned directory is ' 1072 msg = ('Can\'t update/checkout %s if an unversioned directory is '
1051 'present. Delete the directory and try again.') 1073 'present. Delete the directory and try again.')
1052 raise gclient_utils.Error(msg % self.checkout_path) 1074 raise gclient_utils.Error(msg % self.checkout_path)
1053 1075
1054 BASE_URLS = { 1076 BASE_URLS = {
1055 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/', 1077 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/',
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1165 if d[0][0] == '!': 1187 if d[0][0] == '!':
1166 print 'You can pass --force to enable automatic removal.' 1188 print 'You can pass --force to enable automatic removal.'
1167 raise e 1189 raise e
1168 1190
1169 # Retrieve the current HEAD version because svn is slow at null updates. 1191 # Retrieve the current HEAD version because svn is slow at null updates.
1170 if options.manually_grab_svn_rev and not revision: 1192 if options.manually_grab_svn_rev and not revision:
1171 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) 1193 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL'])
1172 revision = str(from_info_live['Revision']) 1194 revision = str(from_info_live['Revision'])
1173 rev_str = ' at %s' % revision 1195 rev_str = ' at %s' % revision
1174 1196
1175 if from_info['URL'] != base_url: 1197 if from_info['URL'].rstrip('/') != base_url.rstrip('/'):
1176 # The repository url changed, need to switch. 1198 # The repository url changed, need to switch.
1177 try: 1199 try:
1178 to_info = scm.SVN.CaptureRemoteInfo(url) 1200 to_info = scm.SVN.CaptureRemoteInfo(url)
1179 except (gclient_utils.Error, subprocess2.CalledProcessError): 1201 except (gclient_utils.Error, subprocess2.CalledProcessError):
1180 # The url is invalid or the server is not accessible, it's safer to bail 1202 # The url is invalid or the server is not accessible, it's safer to bail
1181 # out right now. 1203 # out right now.
1182 raise gclient_utils.Error('This url is unreachable: %s' % url) 1204 raise gclient_utils.Error('This url is unreachable: %s' % url)
1183 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) 1205 can_switch = ((from_info['Repository Root'] != to_info['Repository Root'])
1184 and (from_info['UUID'] == to_info['UUID'])) 1206 and (from_info['UUID'] == to_info['UUID']))
1185 if can_switch: 1207 if can_switch:
(...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1401 new_command.append('--force') 1423 new_command.append('--force')
1402 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1424 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1403 new_command.extend(('--accept', 'theirs-conflict')) 1425 new_command.extend(('--accept', 'theirs-conflict'))
1404 elif options.manually_grab_svn_rev: 1426 elif options.manually_grab_svn_rev:
1405 new_command.append('--force') 1427 new_command.append('--force')
1406 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1428 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1407 new_command.extend(('--accept', 'postpone')) 1429 new_command.extend(('--accept', 'postpone'))
1408 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: 1430 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]:
1409 new_command.extend(('--accept', 'postpone')) 1431 new_command.extend(('--accept', 'postpone'))
1410 return new_command 1432 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