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 logging | 7 import logging |
| 8 import os | 8 import os |
| 9 import posixpath | 9 import posixpath |
| 10 import re | 10 import re |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 230 # Not a fatal error, or even very interesting in a non-git-submodule | 230 # Not a fatal error, or even very interesting in a non-git-submodule |
| 231 # world. So just keep it quiet. | 231 # world. So just keep it quiet. |
| 232 pass | 232 pass |
| 233 try: | 233 try: |
| 234 gclient_utils.CheckCallAndFilter(cmd3, **kwargs) | 234 gclient_utils.CheckCallAndFilter(cmd3, **kwargs) |
| 235 except subprocess2.CalledProcessError: | 235 except subprocess2.CalledProcessError: |
| 236 gclient_utils.CheckCallAndFilter(cmd3 + ['always'], **kwargs) | 236 gclient_utils.CheckCallAndFilter(cmd3 + ['always'], **kwargs) |
| 237 | 237 |
| 238 gclient_utils.CheckCallAndFilter(cmd4, **kwargs) | 238 gclient_utils.CheckCallAndFilter(cmd4, **kwargs) |
| 239 | 239 |
| 240 def _FetchAndReset(self, revision, file_list, options): | |
| 241 """Equivalent to git fetch; git reset.""" | |
| 242 quiet = [] | |
| 243 if not options.verbose: | |
| 244 quiet = ['--quiet'] | |
| 245 self._UpdateBranchHeads(options, fetch=False) | |
| 246 self._Run(['fetch', 'origin', '--prune'] + quiet, options) | |
| 247 self._Run(['reset', '--hard', revision] + quiet, options) | |
| 248 self.UpdateSubmoduleConfig() | |
| 249 files = self._Capture(['ls-files']).splitlines() | |
| 250 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | |
| 251 | |
| 240 def update(self, options, args, file_list): | 252 def update(self, options, args, file_list): |
| 241 """Runs git to update or transparently checkout the working copy. | 253 """Runs git to update or transparently checkout the working copy. |
| 242 | 254 |
| 243 All updated files will be appended to file_list. | 255 All updated files will be appended to file_list. |
| 244 | 256 |
| 245 Raises: | 257 Raises: |
| 246 Error: if can't get URL for relative path. | 258 Error: if can't get URL for relative path. |
| 247 """ | 259 """ |
| 248 if args: | 260 if args: |
| 249 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) | 261 raise gclient_utils.Error("Unsupported argument(s): %s" % ",".join(args)) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 331 if (current_url != url and | 343 if (current_url != url and |
| 332 url != 'git://foo' and | 344 url != 'git://foo' and |
| 333 subprocess2.capture( | 345 subprocess2.capture( |
| 334 ['git', 'config', 'remote.origin.gclient-auto-fix-url'], | 346 ['git', 'config', 'remote.origin.gclient-auto-fix-url'], |
| 335 cwd=self.checkout_path).strip() != 'False'): | 347 cwd=self.checkout_path).strip() != 'False'): |
| 336 print('_____ switching %s to a new upstream' % self.relpath) | 348 print('_____ switching %s to a new upstream' % self.relpath) |
| 337 # Make sure it's clean | 349 # Make sure it's clean |
| 338 self._CheckClean(rev_str) | 350 self._CheckClean(rev_str) |
| 339 # Switch over to the new upstream | 351 # Switch over to the new upstream |
| 340 self._Run(['remote', 'set-url', 'origin', url], options) | 352 self._Run(['remote', 'set-url', 'origin', url], options) |
| 341 quiet = [] | 353 self._FetchAndReset(revision, file_list, options) |
| 342 if not options.verbose: | |
| 343 quiet = ['--quiet'] | |
| 344 self._UpdateBranchHeads(options, fetch=False) | |
| 345 self._Run(['fetch', 'origin', '--prune'] + quiet, options) | |
| 346 self._Run(['reset', '--hard', revision] + quiet, options) | |
| 347 self.UpdateSubmoduleConfig() | |
| 348 files = self._Capture(['ls-files']).splitlines() | |
| 349 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | |
| 350 return | 354 return |
| 351 | 355 |
| 356 if not self._IsValidGitRepo(): | |
| 357 # .git directory is hosed for some reason, set it back up. | |
| 358 print('_____ %s/.git is corrupted, rebuilding' % self.relpath) | |
| 359 self._Run(['init'], options) | |
| 360 self._Run(['remote', 'set-url', 'origin', url], options) | |
| 361 | |
| 362 if not self._HasHead(): | |
| 363 # Previous checkout was aborted before branches could be created in repo, | |
| 364 # so we need to reconstruct them here. | |
| 365 self._Run(['pull', 'origin', 'master'], options) | |
| 366 self._FetchAndReset(revision, file_list, options) | |
| 367 | |
| 352 cur_branch = self._GetCurrentBranch() | 368 cur_branch = self._GetCurrentBranch() |
| 353 | 369 |
| 354 # Cases: | 370 # Cases: |
| 355 # 0) HEAD is detached. Probably from our initial clone. | 371 # 0) HEAD is detached. Probably from our initial clone. |
| 356 # - make sure HEAD is contained by a named ref, then update. | 372 # - make sure HEAD is contained by a named ref, then update. |
| 357 # Cases 1-4. HEAD is a branch. | 373 # Cases 1-4. HEAD is a branch. |
| 358 # 1) current branch is not tracking a remote branch (could be git-svn) | 374 # 1) current branch is not tracking a remote branch (could be git-svn) |
| 359 # - try to rebase onto the new hash or branch | 375 # - try to rebase onto the new hash or branch |
| 360 # 2) current branch is tracking a remote branch with local committed | 376 # 2) current branch is tracking a remote branch with local committed |
| 361 # changes, but the DEPS file switched to point to a hash | 377 # changes, but the DEPS file switched to point to a hash |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 794 "manually.\ncd %s && git " % | 810 "manually.\ncd %s && git " % |
| 795 self.checkout_path | 811 self.checkout_path |
| 796 + "%s" % ' '.join(rebase_cmd)) | 812 + "%s" % ' '.join(rebase_cmd)) |
| 797 | 813 |
| 798 print(rebase_output.strip()) | 814 print(rebase_output.strip()) |
| 799 if not options.verbose: | 815 if not options.verbose: |
| 800 # Make the output a little prettier. It's nice to have some | 816 # Make the output a little prettier. It's nice to have some |
| 801 # whitespace between projects when syncing. | 817 # whitespace between projects when syncing. |
| 802 print('') | 818 print('') |
| 803 | 819 |
| 820 def _IsValidGitRepo(self): | |
| 821 """Returns if the directory is a valid git repository. | |
| 822 | |
| 823 Checks if git status works. | |
| 824 """ | |
| 825 try: | |
| 826 self._Capture(['status']) | |
|
Isaac (away)
2013/07/16 10:06:21
status is a expensive command on some projects (li
| |
| 827 return True | |
| 828 except subprocess2.CalledProcessError: | |
| 829 return False | |
| 830 | |
| 831 def _HasHead(self): | |
| 832 """Returns True if any commit is checked out. | |
| 833 | |
| 834 This is done by checking if rev-parse HEAD works in the current repository. | |
| 835 """ | |
| 836 try: | |
| 837 self._GetCurrentBranch() | |
| 838 return True | |
| 839 except subprocess2.CalledProcessError: | |
| 840 return False | |
| 841 | |
| 804 @staticmethod | 842 @staticmethod |
| 805 def _CheckMinVersion(min_version): | 843 def _CheckMinVersion(min_version): |
| 806 (ok, current_version) = scm.GIT.AssertVersion(min_version) | 844 (ok, current_version) = scm.GIT.AssertVersion(min_version) |
| 807 if not ok: | 845 if not ok: |
| 808 raise gclient_utils.Error('git version %s < minimum required %s' % | 846 raise gclient_utils.Error('git version %s < minimum required %s' % |
| 809 (current_version, min_version)) | 847 (current_version, min_version)) |
| 810 | 848 |
| 811 def _IsRebasing(self): | 849 def _IsRebasing(self): |
| 812 # Check for any of REBASE-i/REBASE-m/REBASE/AM. Unfortunately git doesn't | 850 # Check for any of REBASE-i/REBASE-m/REBASE/AM. Unfortunately git doesn't |
| 813 # have a plumbing command to determine whether a rebase is in progress, so | 851 # have a plumbing command to determine whether a rebase is in progress, so |
| (...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1291 new_command.append('--force') | 1329 new_command.append('--force') |
| 1292 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1330 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1293 new_command.extend(('--accept', 'theirs-conflict')) | 1331 new_command.extend(('--accept', 'theirs-conflict')) |
| 1294 elif options.manually_grab_svn_rev: | 1332 elif options.manually_grab_svn_rev: |
| 1295 new_command.append('--force') | 1333 new_command.append('--force') |
| 1296 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1334 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1297 new_command.extend(('--accept', 'postpone')) | 1335 new_command.extend(('--accept', 'postpone')) |
| 1298 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1336 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
| 1299 new_command.extend(('--accept', 'postpone')) | 1337 new_command.extend(('--accept', 'postpone')) |
| 1300 return new_command | 1338 return new_command |
| OLD | NEW |