| 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 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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)) | |
| 318 self._Clone(revision, url, options) | 303 self._Clone(revision, url, options) |
| 319 self.UpdateSubmoduleConfig() | 304 self.UpdateSubmoduleConfig() |
| 320 if file_list is not None: | 305 if file_list is not None: |
| 321 files = self._Capture(['ls-files']).splitlines() | 306 files = self._Capture(['ls-files']).splitlines() |
| 322 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 307 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
| 323 if not verbose: | 308 if not verbose: |
| 324 # Make the output a little prettier. It's nice to have some whitespace | 309 # Make the output a little prettier. It's nice to have some whitespace |
| 325 # between projects when cloning. | 310 # between projects when cloning. |
| 326 print('') | 311 print('') |
| 327 return self._Capture(['rev-parse', '--verify', 'HEAD']) | 312 return self._Capture(['rev-parse', '--verify', 'HEAD']) |
| 328 | 313 |
| 329 if not managed: | 314 if not managed: |
| 330 self._UpdateBranchHeads(options, fetch=False) | 315 self._UpdateBranchHeads(options, fetch=False) |
| 331 self.UpdateSubmoduleConfig() | 316 self.UpdateSubmoduleConfig() |
| 332 print ('________ unmanaged solution; skipping %s' % self.relpath) | 317 print ('________ unmanaged solution; skipping %s' % self.relpath) |
| 333 return self._Capture(['rev-parse', '--verify', 'HEAD']) | 318 return self._Capture(['rev-parse', '--verify', 'HEAD']) |
| 334 | 319 |
| 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 |
| 335 # See if the url has changed (the unittests use git://foo for the url, let | 328 # See if the url has changed (the unittests use git://foo for the url, let |
| 336 # that through). | 329 # that through). |
| 337 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) | 330 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) |
| 338 return_early = False | 331 return_early = False |
| 339 # TODO(maruel): Delete url != 'git://foo' since it's just to make the | 332 # TODO(maruel): Delete url != 'git://foo' since it's just to make the |
| 340 # unit test pass. (and update the comment above) | 333 # unit test pass. (and update the comment above) |
| 341 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. | 334 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. |
| 342 # This allows devs to use experimental repos which have a different url | 335 # This allows devs to use experimental repos which have a different url |
| 343 # but whose branch(s) are the same as official repos. | 336 # but whose branch(s) are the same as official repos. |
| 344 if (current_url.rstrip('/') != url.rstrip('/') and | 337 if (current_url != url and |
| 345 url != 'git://foo' and | 338 url != 'git://foo' and |
| 346 subprocess2.capture( | 339 subprocess2.capture( |
| 347 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], | 340 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], |
| 348 cwd=self.checkout_path).strip() != 'False'): | 341 cwd=self.checkout_path).strip() != 'False'): |
| 349 print('_____ switching %s to a new upstream' % self.relpath) | 342 print('_____ switching %s to a new upstream' % self.relpath) |
| 350 # Make sure it's clean | 343 # Make sure it's clean |
| 351 self._CheckClean(rev_str) | 344 self._CheckClean(rev_str) |
| 352 # Switch over to the new upstream | 345 # Switch over to the new upstream |
| 353 self._Run(['remote', 'set-url', self.remote, url], options) | 346 self._Run(['remote', 'set-url', self.remote, url], options) |
| 354 self._FetchAndReset(revision, file_list, options) | 347 self._FetchAndReset(revision, file_list, options) |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 filter_fn=SvnDiffFilterer(self.relpath).Filter) | 992 filter_fn=SvnDiffFilterer(self.relpath).Filter) |
| 1000 | 993 |
| 1001 def update(self, options, args, file_list): | 994 def update(self, options, args, file_list): |
| 1002 """Runs svn to update or transparently checkout the working copy. | 995 """Runs svn to update or transparently checkout the working copy. |
| 1003 | 996 |
| 1004 All updated files will be appended to file_list. | 997 All updated files will be appended to file_list. |
| 1005 | 998 |
| 1006 Raises: | 999 Raises: |
| 1007 Error: if can't get URL for relative path. | 1000 Error: if can't get URL for relative path. |
| 1008 """ | 1001 """ |
| 1009 # Only update if hg is not controlling the directory. | 1002 # Only update if git or 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 |
| 1010 hg_path = os.path.join(self.checkout_path, '.hg') | 1008 hg_path = os.path.join(self.checkout_path, '.hg') |
| 1011 if os.path.exists(hg_path): | 1009 if os.path.exists(hg_path): |
| 1012 print('________ found .hg directory; skipping %s' % self.relpath) | 1010 print('________ found .hg directory; skipping %s' % self.relpath) |
| 1013 return | 1011 return |
| 1014 | 1012 |
| 1015 if args: | 1013 if args: |
| 1016 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) | 1014 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) |
| 1017 | 1015 |
| 1018 # revision is the revision to match. It is None if no revision is specified, | 1016 # revision is the revision to match. It is None if no revision is specified, |
| 1019 # i.e. the 'deps ain't pinned'. | 1017 # i.e. the 'deps ain't pinned'. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1030 # Reconstruct the url. | 1028 # Reconstruct the url. |
| 1031 url = '%s@%s' % (url, revision) | 1029 url = '%s@%s' % (url, revision) |
| 1032 rev_str = ' at %s' % revision | 1030 rev_str = ' at %s' % revision |
| 1033 else: | 1031 else: |
| 1034 managed = False | 1032 managed = False |
| 1035 revision = None | 1033 revision = None |
| 1036 else: | 1034 else: |
| 1037 forced_revision = False | 1035 forced_revision = False |
| 1038 rev_str = '' | 1036 rev_str = '' |
| 1039 | 1037 |
| 1038 # Get the existing scm url and the revision number of the current checkout. |
| 1040 exists = os.path.exists(self.checkout_path) | 1039 exists = os.path.exists(self.checkout_path) |
| 1041 if exists and managed: | 1040 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 | |
| 1052 # Get the existing scm url and the revision number of the current checkout. | |
| 1053 if exists and managed: | |
| 1054 try: | 1041 try: |
| 1055 from_info = scm.SVN.CaptureLocalInfo( | 1042 from_info = scm.SVN.CaptureLocalInfo( |
| 1056 [], os.path.join(self.checkout_path, '.')) | 1043 [], os.path.join(self.checkout_path, '.')) |
| 1057 except (gclient_utils.Error, subprocess2.CalledProcessError): | 1044 except (gclient_utils.Error, subprocess2.CalledProcessError): |
| 1058 if (options.force or | 1045 if options.reset and options.delete_unversioned_trees: |
| 1059 (options.reset and options.delete_unversioned_trees)): | |
| 1060 print 'Removing troublesome path %s' % self.checkout_path | 1046 print 'Removing troublesome path %s' % self.checkout_path |
| 1061 gclient_utils.rmtree(self.checkout_path) | 1047 gclient_utils.rmtree(self.checkout_path) |
| 1062 exists = False | 1048 exists = False |
| 1063 else: | 1049 else: |
| 1064 msg = ('Can\'t update/checkout %s if an unversioned directory is ' | 1050 msg = ('Can\'t update/checkout %s if an unversioned directory is ' |
| 1065 'present. Delete the directory and try again.') | 1051 'present. Delete the directory and try again.') |
| 1066 raise gclient_utils.Error(msg % self.checkout_path) | 1052 raise gclient_utils.Error(msg % self.checkout_path) |
| 1067 | 1053 |
| 1068 BASE_URLS = { | 1054 BASE_URLS = { |
| 1069 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/', | 1055 '/chrome/trunk/src': 'gs://chromium-svn-checkout/chrome/', |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1136 | 1122 |
| 1137 gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path)) | 1123 gclient_utils.safe_makedirs(os.path.dirname(self.checkout_path)) |
| 1138 # We need to checkout. | 1124 # We need to checkout. |
| 1139 command = ['checkout', url, self.checkout_path] | 1125 command = ['checkout', url, self.checkout_path] |
| 1140 command = self._AddAdditionalUpdateFlags(command, options, revision) | 1126 command = self._AddAdditionalUpdateFlags(command, options, revision) |
| 1141 self._RunAndGetFileList(command, options, file_list, self._root_dir) | 1127 self._RunAndGetFileList(command, options, file_list, self._root_dir) |
| 1142 return self.Svnversion() | 1128 return self.Svnversion() |
| 1143 | 1129 |
| 1144 if not managed: | 1130 if not managed: |
| 1145 print ('________ unmanaged solution; skipping %s' % self.relpath) | 1131 print ('________ unmanaged solution; skipping %s' % self.relpath) |
| 1146 if not scm.GIT.IsGitSvn(self.checkout_path): | 1132 return self.Svnversion() |
| 1147 return self.Svnversion() | |
| 1148 return | |
| 1149 | 1133 |
| 1150 if 'URL' not in from_info: | 1134 if 'URL' not in from_info: |
| 1151 raise gclient_utils.Error( | 1135 raise gclient_utils.Error( |
| 1152 ('gclient is confused. Couldn\'t get the url for %s.\n' | 1136 ('gclient is confused. Couldn\'t get the url for %s.\n' |
| 1153 'Try using @unmanaged.\n%s') % ( | 1137 'Try using @unmanaged.\n%s') % ( |
| 1154 self.checkout_path, from_info)) | 1138 self.checkout_path, from_info)) |
| 1155 | 1139 |
| 1156 # Look for locked directories. | 1140 # Look for locked directories. |
| 1157 dir_info = scm.SVN.CaptureStatus( | 1141 dir_info = scm.SVN.CaptureStatus( |
| 1158 None, os.path.join(self.checkout_path, '.')) | 1142 None, os.path.join(self.checkout_path, '.')) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1181 if d[0][0] == '!': | 1165 if d[0][0] == '!': |
| 1182 print 'You can pass --force to enable automatic removal.' | 1166 print 'You can pass --force to enable automatic removal.' |
| 1183 raise e | 1167 raise e |
| 1184 | 1168 |
| 1185 # Retrieve the current HEAD version because svn is slow at null updates. | 1169 # Retrieve the current HEAD version because svn is slow at null updates. |
| 1186 if options.manually_grab_svn_rev and not revision: | 1170 if options.manually_grab_svn_rev and not revision: |
| 1187 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) | 1171 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) |
| 1188 revision = str(from_info_live['Revision']) | 1172 revision = str(from_info_live['Revision']) |
| 1189 rev_str = ' at %s' % revision | 1173 rev_str = ' at %s' % revision |
| 1190 | 1174 |
| 1191 if from_info['URL'].rstrip('/') != base_url.rstrip('/'): | 1175 if from_info['URL'] != base_url: |
| 1192 # The repository url changed, need to switch. | 1176 # The repository url changed, need to switch. |
| 1193 try: | 1177 try: |
| 1194 to_info = scm.SVN.CaptureRemoteInfo(url) | 1178 to_info = scm.SVN.CaptureRemoteInfo(url) |
| 1195 except (gclient_utils.Error, subprocess2.CalledProcessError): | 1179 except (gclient_utils.Error, subprocess2.CalledProcessError): |
| 1196 # The url is invalid or the server is not accessible, it's safer to bail | 1180 # The url is invalid or the server is not accessible, it's safer to bail |
| 1197 # out right now. | 1181 # out right now. |
| 1198 raise gclient_utils.Error('This url is unreachable: %s' % url) | 1182 raise gclient_utils.Error('This url is unreachable: %s' % url) |
| 1199 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) | 1183 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) |
| 1200 and (from_info['UUID'] == to_info['UUID'])) | 1184 and (from_info['UUID'] == to_info['UUID'])) |
| 1201 if can_switch: | 1185 if can_switch: |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1417 new_command.append('--force') | 1401 new_command.append('--force') |
| 1418 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1402 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1419 new_command.extend(('--accept', 'theirs-conflict')) | 1403 new_command.extend(('--accept', 'theirs-conflict')) |
| 1420 elif options.manually_grab_svn_rev: | 1404 elif options.manually_grab_svn_rev: |
| 1421 new_command.append('--force') | 1405 new_command.append('--force') |
| 1422 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1406 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1423 new_command.extend(('--accept', 'postpone')) | 1407 new_command.extend(('--accept', 'postpone')) |
| 1424 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1408 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1425 new_command.extend(('--accept', 'postpone')) | 1409 new_command.extend(('--accept', 'postpone')) |
| 1426 return new_command | 1410 return new_command |
| OLD | NEW |