OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |