Chromium Code Reviews| 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 collections | 7 import collections |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import posixpath | 10 import posixpath |
| (...skipping 284 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 295 if revision.startswith('refs/'): | 295 if revision.startswith('refs/'): |
| 296 rev_type = "branch" | 296 rev_type = "branch" |
| 297 elif revision.startswith(self.remote + '/'): | 297 elif revision.startswith(self.remote + '/'): |
| 298 # For compatibility with old naming, translate 'origin' to 'refs/heads' | 298 # For compatibility with old naming, translate 'origin' to 'refs/heads' |
| 299 revision = revision.replace(self.remote + '/', 'refs/heads/') | 299 revision = revision.replace(self.remote + '/', 'refs/heads/') |
| 300 rev_type = "branch" | 300 rev_type = "branch" |
| 301 else: | 301 else: |
| 302 # hash is also a tag, only make a distinction at checkout | 302 # hash is also a tag, only make a distinction at checkout |
| 303 rev_type = "hash" | 303 rev_type = "hash" |
| 304 | 304 |
| 305 if (not os.path.exists(self.checkout_path) or | 305 if (not os.path.exists(self.checkout_path)): |
| 306 (os.path.isdir(self.checkout_path) and | |
| 307 not os.path.exists(os.path.join(self.checkout_path, '.git')))): | |
| 308 self._Clone(revision, url, options) | 306 self._Clone(revision, url, options) |
| 309 self.UpdateSubmoduleConfig() | 307 self.UpdateSubmoduleConfig() |
| 310 if file_list is not None: | 308 if file_list is not None: |
| 311 files = self._Capture(['ls-files']).splitlines() | 309 files = self._Capture(['ls-files']).splitlines() |
| 312 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 310 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
| 313 if not verbose: | 311 if not verbose: |
| 314 # Make the output a little prettier. It's nice to have some whitespace | 312 # Make the output a little prettier. It's nice to have some whitespace |
| 315 # between projects when cloning. | 313 # between projects when cloning. |
| 316 print('') | 314 print('') |
| 317 return self._Capture(['rev-parse', '--verify', 'HEAD']) | 315 return self._Capture(['rev-parse', '--verify', 'HEAD']) |
| 318 | 316 |
| 319 if not managed: | 317 if not managed: |
| 320 self._UpdateBranchHeads(options, fetch=False) | 318 self._UpdateBranchHeads(options, fetch=False) |
| 321 self.UpdateSubmoduleConfig() | 319 self.UpdateSubmoduleConfig() |
| 322 print ('________ unmanaged solution; skipping %s' % self.relpath) | 320 print ('________ unmanaged solution; skipping %s' % self.relpath) |
| 323 return self._Capture(['rev-parse', '--verify', 'HEAD']) | 321 return self._Capture(['rev-parse', '--verify', 'HEAD']) |
| 324 | 322 |
| 325 if not os.path.exists(os.path.join(self.checkout_path, '.git')): | 323 if not os.path.exists(os.path.join(self.checkout_path, '.git')): |
| 326 raise gclient_utils.Error('\n____ %s%s\n' | 324 if options.force: |
| 327 '\tPath is not a git repo. No .git dir.\n' | 325 # Delete and re-sync. |
| 328 '\tTo resolve:\n' | 326 print('_____ Conflicting directory found in %s. Removing.' |
| 329 '\t\trm -rf %s\n' | 327 % self.checkout_path) |
| 330 '\tAnd run gclient sync again\n' | 328 gclient_utils.rmtree(self.checkout_path) |
| 331 % (self.relpath, rev_str, self.relpath)) | 329 self._Clone(revision, url, options) |
| 330 self.UpdateSubmoduleConfig() | |
| 331 if file_list is not None: | |
| 332 files = self._Capture(['ls-files']).splitlines() | |
| 333 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | |
| 334 if not verbose: | |
| 335 # Make the output a little prettier. It's nice to have some whitespace | |
| 336 # between projects when cloning. | |
| 337 print('') | |
| 338 return self._Capture(['rev-parse', '--verify', 'HEAD']) | |
| 339 else: | |
| 340 raise gclient_utils.Error('\n____ %s%s\n' | |
| 341 '\tPath is not a git repo. No .git dir.\n' | |
| 342 '\tTo resolve:\n' | |
| 343 '\t\trm -rf %s\n' | |
| 344 '\tAnd run gclient sync again\n' | |
| 345 '\tOr run with --force\n' | |
| 346 % (self.relpath, rev_str, self.relpath)) | |
| 332 | 347 |
| 333 # See if the url has changed (the unittests use git://foo for the url, let | 348 # See if the url has changed (the unittests use git://foo for the url, let |
| 334 # that through). | 349 # that through). |
| 335 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) | 350 current_url = self._Capture(['config', 'remote.%s.url' % self.remote]) |
| 336 return_early = False | 351 return_early = False |
| 337 # TODO(maruel): Delete url != 'git://foo' since it's just to make the | 352 # TODO(maruel): Delete url != 'git://foo' since it's just to make the |
| 338 # unit test pass. (and update the comment above) | 353 # unit test pass. (and update the comment above) |
| 339 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. | 354 # Skip url auto-correction if remote.origin.gclient-auto-fix-url is set. |
| 340 # This allows devs to use experimental repos which have a different url | 355 # This allows devs to use experimental repos which have a different url |
| 341 # but whose branch(s) are the same as official repos. | 356 # but whose branch(s) are the same as official repos. |
| 342 if (current_url != url and | 357 if (current_url.rstrip('/') != url.rstrip('/') and |
|
borenet
2014/02/28 21:54:23
The smoketest was behaving incorrectly because of
| |
| 343 url != 'git://foo' and | 358 url != 'git://foo' and |
| 344 subprocess2.capture( | 359 subprocess2.capture( |
| 345 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], | 360 ['git', 'config', 'remote.%s.gclient-auto-fix-url' % self.remote], |
| 346 cwd=self.checkout_path).strip() != 'False'): | 361 cwd=self.checkout_path).strip() != 'False'): |
| 347 print('_____ switching %s to a new upstream' % self.relpath) | 362 print('_____ switching %s to a new upstream' % self.relpath) |
| 348 # Make sure it's clean | 363 # Make sure it's clean |
| 349 self._CheckClean(rev_str) | 364 self._CheckClean(rev_str) |
| 350 # Switch over to the new upstream | 365 # Switch over to the new upstream |
| 351 self._Run(['remote', 'set-url', self.remote, url], options) | 366 self._Run(['remote', 'set-url', self.remote, url], options) |
| 352 self._FetchAndReset(revision, file_list, options) | 367 self._FetchAndReset(revision, file_list, options) |
| (...skipping 744 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1097 filter_fn=SvnDiffFilterer(self.relpath).Filter) | 1112 filter_fn=SvnDiffFilterer(self.relpath).Filter) |
| 1098 | 1113 |
| 1099 def update(self, options, args, file_list): | 1114 def update(self, options, args, file_list): |
| 1100 """Runs svn to update or transparently checkout the working copy. | 1115 """Runs svn to update or transparently checkout the working copy. |
| 1101 | 1116 |
| 1102 All updated files will be appended to file_list. | 1117 All updated files will be appended to file_list. |
| 1103 | 1118 |
| 1104 Raises: | 1119 Raises: |
| 1105 Error: if can't get URL for relative path. | 1120 Error: if can't get URL for relative path. |
| 1106 """ | 1121 """ |
| 1107 # Only update if git or hg is not controlling the directory. | 1122 # Only update if hg is not controlling the directory. |
| 1108 git_path = os.path.join(self.checkout_path, '.git') | |
| 1109 if os.path.exists(git_path): | |
| 1110 print('________ found .git directory; skipping %s' % self.relpath) | |
| 1111 return | |
| 1112 | |
| 1113 hg_path = os.path.join(self.checkout_path, '.hg') | 1123 hg_path = os.path.join(self.checkout_path, '.hg') |
| 1114 if os.path.exists(hg_path): | 1124 if os.path.exists(hg_path): |
| 1115 print('________ found .hg directory; skipping %s' % self.relpath) | 1125 print('________ found .hg directory; skipping %s' % self.relpath) |
| 1116 return | 1126 return |
| 1117 | 1127 |
| 1118 if args: | 1128 if args: |
| 1119 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) | 1129 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) |
| 1120 | 1130 |
| 1121 # revision is the revision to match. It is None if no revision is specified, | 1131 # revision is the revision to match. It is None if no revision is specified, |
| 1122 # i.e. the 'deps ain't pinned'. | 1132 # i.e. the 'deps ain't pinned'. |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 1133 # Reconstruct the url. | 1143 # Reconstruct the url. |
| 1134 url = '%s@%s' % (url, revision) | 1144 url = '%s@%s' % (url, revision) |
| 1135 rev_str = ' at %s' % revision | 1145 rev_str = ' at %s' % revision |
| 1136 else: | 1146 else: |
| 1137 managed = False | 1147 managed = False |
| 1138 revision = None | 1148 revision = None |
| 1139 else: | 1149 else: |
| 1140 forced_revision = False | 1150 forced_revision = False |
| 1141 rev_str = '' | 1151 rev_str = '' |
| 1142 | 1152 |
| 1153 exists = os.path.exists(self.checkout_path) | |
| 1154 if exists and managed: | |
| 1155 # Git is only okay if it's a git-svn checkout of the right repo. | |
| 1156 if scm.GIT.IsGit(self.checkout_path): | |
|
szager1
2014/02/28 22:17:52
Isn't the scm.GIT.IsGit check redundant? Can't yo
borenet
2014/03/03 18:31:11
Not quite. As written, the checkout is deleted if
szager1
2014/03/03 18:50:40
But wouldn't the next stanza take care of the pure
szager1
2014/03/03 18:54:20
Ah, I see... the next stanza relies on options.res
borenet
2014/03/03 19:14:22
Okay, I can remove everything but the early return
borenet
2014/03/03 21:09:05
Done.
| |
| 1157 if scm.GIT.IsGitSvn(self.checkout_path): | |
| 1158 remote_url = scm.GIT.Capture(['config', '--local', '--get', | |
| 1159 'svn-remote.svn.url'], | |
| 1160 cwd=self.checkout_path).rstrip() | |
| 1161 if remote_url.rstrip('/') == base_url.rstrip('/'): | |
| 1162 print('\n_____ %s looks like a git-svn checkout. Skipping.' | |
| 1163 % self.relpath) | |
| 1164 return # TODO(borenet): Get the svn revision number? | |
| 1165 | |
| 1166 if not options.force and not options.reset: | |
| 1167 raise gclient_utils.Error( | |
| 1168 '%s contains a git checkout. Delete the directory and try again.' | |
| 1169 % self.checkout_path) | |
| 1170 else: | |
| 1171 gclient_utils.rmtree(self.checkout_path) | |
| 1172 exists = False | |
| 1173 | |
| 1143 # Get the existing scm url and the revision number of the current checkout. | 1174 # Get the existing scm url and the revision number of the current checkout. |
| 1144 exists = os.path.exists(self.checkout_path) | |
| 1145 if exists and managed: | 1175 if exists and managed: |
| 1146 try: | 1176 try: |
| 1147 from_info = scm.SVN.CaptureLocalInfo( | 1177 from_info = scm.SVN.CaptureLocalInfo( |
| 1148 [], os.path.join(self.checkout_path, '.')) | 1178 [], os.path.join(self.checkout_path, '.')) |
| 1149 except (gclient_utils.Error, subprocess2.CalledProcessError): | 1179 except (gclient_utils.Error, subprocess2.CalledProcessError): |
| 1150 if options.reset and options.delete_unversioned_trees: | 1180 if options.reset and options.delete_unversioned_trees: |
| 1151 print 'Removing troublesome path %s' % self.checkout_path | 1181 print 'Removing troublesome path %s' % self.checkout_path |
| 1152 gclient_utils.rmtree(self.checkout_path) | 1182 gclient_utils.rmtree(self.checkout_path) |
| 1153 exists = False | 1183 exists = False |
| 1154 else: | 1184 else: |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1270 if d[0][0] == '!': | 1300 if d[0][0] == '!': |
| 1271 print 'You can pass --force to enable automatic removal.' | 1301 print 'You can pass --force to enable automatic removal.' |
| 1272 raise e | 1302 raise e |
| 1273 | 1303 |
| 1274 # Retrieve the current HEAD version because svn is slow at null updates. | 1304 # Retrieve the current HEAD version because svn is slow at null updates. |
| 1275 if options.manually_grab_svn_rev and not revision: | 1305 if options.manually_grab_svn_rev and not revision: |
| 1276 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) | 1306 from_info_live = scm.SVN.CaptureRemoteInfo(from_info['URL']) |
| 1277 revision = str(from_info_live['Revision']) | 1307 revision = str(from_info_live['Revision']) |
| 1278 rev_str = ' at %s' % revision | 1308 rev_str = ' at %s' % revision |
| 1279 | 1309 |
| 1280 if from_info['URL'] != base_url: | 1310 if from_info['URL'].rstrip('/') != base_url.rstrip('/'): |
| 1281 # The repository url changed, need to switch. | 1311 # The repository url changed, need to switch. |
| 1282 try: | 1312 try: |
| 1283 to_info = scm.SVN.CaptureRemoteInfo(url) | 1313 to_info = scm.SVN.CaptureRemoteInfo(url) |
| 1284 except (gclient_utils.Error, subprocess2.CalledProcessError): | 1314 except (gclient_utils.Error, subprocess2.CalledProcessError): |
| 1285 # The url is invalid or the server is not accessible, it's safer to bail | 1315 # The url is invalid or the server is not accessible, it's safer to bail |
| 1286 # out right now. | 1316 # out right now. |
| 1287 raise gclient_utils.Error('This url is unreachable: %s' % url) | 1317 raise gclient_utils.Error('This url is unreachable: %s' % url) |
| 1288 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) | 1318 can_switch = ((from_info['Repository Root'] != to_info['Repository Root']) |
| 1289 and (from_info['UUID'] == to_info['UUID'])) | 1319 and (from_info['UUID'] == to_info['UUID'])) |
| 1290 if can_switch: | 1320 if can_switch: |
| (...skipping 215 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1506 new_command.append('--force') | 1536 new_command.append('--force') |
| 1507 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1537 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1508 new_command.extend(('--accept', 'theirs-conflict')) | 1538 new_command.extend(('--accept', 'theirs-conflict')) |
| 1509 elif options.manually_grab_svn_rev: | 1539 elif options.manually_grab_svn_rev: |
| 1510 new_command.append('--force') | 1540 new_command.append('--force') |
| 1511 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1541 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1512 new_command.extend(('--accept', 'postpone')) | 1542 new_command.extend(('--accept', 'postpone')) |
| 1513 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1543 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1514 new_command.extend(('--accept', 'postpone')) | 1544 new_command.extend(('--accept', 'postpone')) |
| 1515 return new_command | 1545 return new_command |
| OLD | NEW |