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 298 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 # unit test pass. (and update the comment above) | 309 # unit test pass. (and update the comment above) |
310 if current_url != url and url != 'git://foo': | 310 if current_url != url and url != 'git://foo': |
311 print('_____ switching %s to a new upstream' % self.relpath) | 311 print('_____ switching %s to a new upstream' % self.relpath) |
312 # Make sure it's clean | 312 # Make sure it's clean |
313 self._CheckClean(rev_str) | 313 self._CheckClean(rev_str) |
314 # Switch over to the new upstream | 314 # Switch over to the new upstream |
315 self._Run(['remote', 'set-url', 'origin', url], options) | 315 self._Run(['remote', 'set-url', 'origin', url], options) |
316 quiet = [] | 316 quiet = [] |
317 if not options.verbose: | 317 if not options.verbose: |
318 quiet = ['--quiet'] | 318 quiet = ['--quiet'] |
| 319 self._UpdateBranchHeads(options, fetch=False) |
319 self._Run(['fetch', 'origin', '--prune'] + quiet, options) | 320 self._Run(['fetch', 'origin', '--prune'] + quiet, options) |
320 self._Run(['reset', '--hard', revision] + quiet, options) | 321 self._Run(['reset', '--hard', revision] + quiet, options) |
321 self.UpdateSubmoduleConfig() | 322 self.UpdateSubmoduleConfig() |
322 files = self._Capture(['ls-files']).splitlines() | 323 files = self._Capture(['ls-files']).splitlines() |
323 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) | 324 file_list.extend([os.path.join(self.checkout_path, f) for f in files]) |
324 return | 325 return |
325 | 326 |
326 cur_branch = self._GetCurrentBranch() | 327 cur_branch = self._GetCurrentBranch() |
327 | 328 |
328 # Cases: | 329 # Cases: |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
377 print(str(e)) | 378 print(str(e)) |
378 print('Sleeping %.1f seconds and retrying...' % backoff_time) | 379 print('Sleeping %.1f seconds and retrying...' % backoff_time) |
379 time.sleep(backoff_time) | 380 time.sleep(backoff_time) |
380 backoff_time *= 1.3 | 381 backoff_time *= 1.3 |
381 continue | 382 continue |
382 raise | 383 raise |
383 | 384 |
384 if verbose: | 385 if verbose: |
385 print(remote_output.strip()) | 386 print(remote_output.strip()) |
386 | 387 |
| 388 self._UpdateBranchHeads(options, fetch=True) |
| 389 |
387 # This is a big hammer, debatable if it should even be here... | 390 # This is a big hammer, debatable if it should even be here... |
388 if options.force or options.reset: | 391 if options.force or options.reset: |
389 self._Run(['reset', '--hard', 'HEAD'], options) | 392 self._Run(['reset', '--hard', 'HEAD'], options) |
390 | 393 |
391 if current_type == 'detached': | 394 if current_type == 'detached': |
392 # case 0 | 395 # case 0 |
393 self._CheckClean(rev_str) | 396 self._CheckClean(rev_str) |
394 self._CheckDetachedHead(rev_str, options) | 397 self._CheckDetachedHead(rev_str, options) |
395 self._Capture(['checkout', '--quiet', '%s' % revision]) | 398 self._Capture(['checkout', '--quiet', '%s' % revision]) |
396 if not printed_path: | 399 if not printed_path: |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
685 # Too bad we don't have access to the actual output yet. | 688 # Too bad we don't have access to the actual output yet. |
686 # We should check for "transfer closed with NNN bytes remaining to | 689 # We should check for "transfer closed with NNN bytes remaining to |
687 # read". In the meantime, just make sure .git exists. | 690 # read". In the meantime, just make sure .git exists. |
688 if (e.returncode == 128 and | 691 if (e.returncode == 128 and |
689 os.path.exists(os.path.join(self.checkout_path, '.git'))): | 692 os.path.exists(os.path.join(self.checkout_path, '.git'))): |
690 print(str(e)) | 693 print(str(e)) |
691 print('Retrying...') | 694 print('Retrying...') |
692 continue | 695 continue |
693 raise e | 696 raise e |
694 | 697 |
695 for _ in range(3): | 698 # Update the "branch-heads" remote-tracking branches, since we might need it |
696 try: | 699 # to checkout a specific revision below. |
697 # Add the "branch-heads" refspecs. Do this separately from the clone | 700 self._UpdateBranchHeads(options, fetch=True) |
698 # command since apparently some versions of git don't support 'clone | |
699 # --config'. | |
700 # Don't assume 'with_branch_heads' is added by 'gclient sync' setup, | |
701 # since _Clone() can by reached in roundabout ways (e.g. 'gclient | |
702 # revert'). | |
703 if hasattr(options, 'with_branch_heads') and options.with_branch_heads: | |
704 config_cmd = ['config', 'remote.origin.fetch', | |
705 '+refs/branch-heads/*:refs/remotes/branch-heads/*', | |
706 '^\\+refs/branch-heads/\\*:.*$'] | |
707 self._Run(config_cmd, options) | |
708 | |
709 # Update the "branch-heads" remote-tracking branches, since we might | |
710 # need it to checkout a specific revision below. | |
711 fetch_cmd = ['fetch', 'origin'] | |
712 if options.verbose: | |
713 fetch_cmd.append('--verbose') | |
714 self._Run(fetch_cmd, options) | |
715 break | |
716 except subprocess2.CalledProcessError, e: | |
717 print(str(e)) | |
718 print('Retrying...') | |
719 continue | |
720 | 701 |
721 if detach_head: | 702 if detach_head: |
722 # Squelch git's very verbose detached HEAD warning and use our own | 703 # Squelch git's very verbose detached HEAD warning and use our own |
723 self._Capture(['checkout', '--quiet', '%s' % revision]) | 704 self._Capture(['checkout', '--quiet', '%s' % revision]) |
724 print( | 705 print( |
725 ('Checked out %s to a detached HEAD. Before making any commits\n' | 706 ('Checked out %s to a detached HEAD. Before making any commits\n' |
726 'in this repo, you should use \'git checkout <branch>\' to switch to\n' | 707 'in this repo, you should use \'git checkout <branch>\' to switch to\n' |
727 'an existing branch or use \'git checkout origin -b <branch>\' to\n' | 708 'an existing branch or use \'git checkout origin -b <branch>\' to\n' |
728 'create a new branch for your work.') % revision) | 709 'create a new branch for your work.') % revision) |
729 | 710 |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
863 if branch == 'HEAD': | 844 if branch == 'HEAD': |
864 return None | 845 return None |
865 return branch | 846 return branch |
866 | 847 |
867 def _Capture(self, args): | 848 def _Capture(self, args): |
868 return subprocess2.check_output( | 849 return subprocess2.check_output( |
869 ['git'] + args, | 850 ['git'] + args, |
870 stderr=subprocess2.PIPE, | 851 stderr=subprocess2.PIPE, |
871 cwd=self.checkout_path).strip() | 852 cwd=self.checkout_path).strip() |
872 | 853 |
| 854 def _UpdateBranchHeads(self, options, fetch=False): |
| 855 """Adds, and optionally fetches, "branch-heads" refspecs if requested.""" |
| 856 if hasattr(options, 'with_branch_heads') and options.with_branch_heads: |
| 857 backoff_time = 5 |
| 858 for _ in range(3): |
| 859 try: |
| 860 config_cmd = ['config', 'remote.origin.fetch', |
| 861 '+refs/branch-heads/*:refs/remotes/branch-heads/*', |
| 862 '^\\+refs/branch-heads/\\*:.*$'] |
| 863 self._Run(config_cmd, options) |
| 864 if fetch: |
| 865 fetch_cmd = ['fetch', 'origin'] |
| 866 if options.verbose: |
| 867 fetch_cmd.append('--verbose') |
| 868 self._Run(fetch_cmd, options) |
| 869 break |
| 870 except subprocess2.CalledProcessError, e: |
| 871 print(str(e)) |
| 872 print('Retrying in %.1f seconds...' % backoff_time) |
| 873 time.sleep(backoff_time) |
| 874 backoff_time *= 1.3 |
| 875 |
873 def _Run(self, args, options, **kwargs): | 876 def _Run(self, args, options, **kwargs): |
874 kwargs.setdefault('cwd', self.checkout_path) | 877 kwargs.setdefault('cwd', self.checkout_path) |
875 kwargs.setdefault('print_stdout', True) | 878 kwargs.setdefault('print_stdout', True) |
876 stdout = kwargs.get('stdout', sys.stdout) | 879 stdout = kwargs.get('stdout', sys.stdout) |
877 stdout.write('\n________ running \'git %s\' in \'%s\'\n' % ( | 880 stdout.write('\n________ running \'git %s\' in \'%s\'\n' % ( |
878 ' '.join(args), kwargs['cwd'])) | 881 ' '.join(args), kwargs['cwd'])) |
879 gclient_utils.CheckCallAndFilter(['git'] + args, **kwargs) | 882 gclient_utils.CheckCallAndFilter(['git'] + args, **kwargs) |
880 | 883 |
881 | 884 |
882 class SVNWrapper(SCMWrapper): | 885 class SVNWrapper(SCMWrapper): |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1254 new_command.append('--force') | 1257 new_command.append('--force') |
1255 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1258 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
1256 new_command.extend(('--accept', 'theirs-conflict')) | 1259 new_command.extend(('--accept', 'theirs-conflict')) |
1257 elif options.manually_grab_svn_rev: | 1260 elif options.manually_grab_svn_rev: |
1258 new_command.append('--force') | 1261 new_command.append('--force') |
1259 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1262 if command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
1260 new_command.extend(('--accept', 'postpone')) | 1263 new_command.extend(('--accept', 'postpone')) |
1261 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: | 1264 elif command[0] != 'checkout' and scm.SVN.AssertVersion('1.6')[0]: |
1262 new_command.extend(('--accept', 'postpone')) | 1265 new_command.extend(('--accept', 'postpone')) |
1263 return new_command | 1266 return new_command |
OLD | NEW |