| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 # Monkeypatch IMapIterator so that Ctrl-C can kill everything properly. | 5 # Monkeypatch IMapIterator so that Ctrl-C can kill everything properly. |
| 6 # Derived from https://gist.github.com/aljungberg/626518 | 6 # Derived from https://gist.github.com/aljungberg/626518 |
| 7 import multiprocessing.pool | 7 import multiprocessing.pool |
| 8 from multiprocessing.pool import IMapIterator | 8 from multiprocessing.pool import IMapIterator |
| 9 def wrapper(func): | 9 def wrapper(func): |
| 10 def wrap(self, timeout=None): | 10 def wrap(self, timeout=None): |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 84 # crbug.com/315421 | 84 # crbug.com/315421 |
| 85 r'The requested URL returned error: 500 while accessing', | 85 r'The requested URL returned error: 500 while accessing', |
| 86 | 86 |
| 87 # crbug.com/388876 | 87 # crbug.com/388876 |
| 88 r'Connection timed out', | 88 r'Connection timed out', |
| 89 ) | 89 ) |
| 90 | 90 |
| 91 GIT_TRANSIENT_ERRORS_RE = re.compile('|'.join(GIT_TRANSIENT_ERRORS), | 91 GIT_TRANSIENT_ERRORS_RE = re.compile('|'.join(GIT_TRANSIENT_ERRORS), |
| 92 re.IGNORECASE) | 92 re.IGNORECASE) |
| 93 | 93 |
| 94 # First version where the for-each-ref command's format string supported the |
| 95 # upstream:track token. |
| 96 MIN_UPSTREAM_TRACK_GIT_VERSION = (1, 9) |
| 94 | 97 |
| 95 class BadCommitRefException(Exception): | 98 class BadCommitRefException(Exception): |
| 96 def __init__(self, refs): | 99 def __init__(self, refs): |
| 97 msg = ('one of %s does not seem to be a valid commitref.' % | 100 msg = ('one of %s does not seem to be a valid commitref.' % |
| 98 str(refs)) | 101 str(refs)) |
| 99 super(BadCommitRefException, self).__init__(msg) | 102 super(BadCommitRefException, self).__init__(msg) |
| 100 | 103 |
| 101 | 104 |
| 102 def memoize_one(**kwargs): | 105 def memoize_one(**kwargs): |
| 103 """Memoizes a single-argument pure function. | 106 """Memoizes a single-argument pure function. |
| (...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 429 base = actual_merge_base | 432 base = actual_merge_base |
| 430 manual_merge_base(branch, base, parent) | 433 manual_merge_base(branch, base, parent) |
| 431 | 434 |
| 432 return base | 435 return base |
| 433 | 436 |
| 434 | 437 |
| 435 def hash_multi(*reflike): | 438 def hash_multi(*reflike): |
| 436 return run('rev-parse', *reflike).splitlines() | 439 return run('rev-parse', *reflike).splitlines() |
| 437 | 440 |
| 438 | 441 |
| 439 def hash_one(reflike): | 442 def hash_one(reflike, short=False): |
| 440 return run('rev-parse', reflike) | 443 args = ['rev-parse', reflike] |
| 444 if short: |
| 445 args.insert(1, '--short') |
| 446 return run(*args) |
| 441 | 447 |
| 442 | 448 |
| 443 def in_rebase(): | 449 def in_rebase(): |
| 444 git_dir = run('rev-parse', '--git-dir') | 450 git_dir = run('rev-parse', '--git-dir') |
| 445 return ( | 451 return ( |
| 446 os.path.exists(os.path.join(git_dir, 'rebase-merge')) or | 452 os.path.exists(os.path.join(git_dir, 'rebase-merge')) or |
| 447 os.path.exists(os.path.join(git_dir, 'rebase-apply'))) | 453 os.path.exists(os.path.join(git_dir, 'rebase-apply'))) |
| 448 | 454 |
| 449 | 455 |
| 450 def intern_f(f, kind='blob'): | 456 def intern_f(f, kind='blob'): |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 return None | 715 return None |
| 710 return ret | 716 return ret |
| 711 | 717 |
| 712 | 718 |
| 713 def upstream(branch): | 719 def upstream(branch): |
| 714 try: | 720 try: |
| 715 return run('rev-parse', '--abbrev-ref', '--symbolic-full-name', | 721 return run('rev-parse', '--abbrev-ref', '--symbolic-full-name', |
| 716 branch+'@{upstream}') | 722 branch+'@{upstream}') |
| 717 except subprocess2.CalledProcessError: | 723 except subprocess2.CalledProcessError: |
| 718 return None | 724 return None |
| 725 |
| 726 def get_git_version(): |
| 727 """Returns a tuple that contains the numeric components of the current git |
| 728 version.""" |
| 729 version_string = run('--version') |
| 730 version_match = re.search(r'(\d+.)+(\d+)', version_string) |
| 731 version = version_match.group() if version_match else '' |
| 732 |
| 733 return tuple(int(x) for x in version.split('.')) |
| 734 |
| 735 |
| 736 def get_all_tracking_info(): |
| 737 format_string = ( |
| 738 '--format=%(refname:short):%(objectname:short):%(upstream:short):') |
| 739 |
| 740 # This is not covered by the depot_tools CQ which only has git version 1.8. |
| 741 if get_git_version() >= MIN_UPSTREAM_TRACK_GIT_VERSION: # pragma: no cover |
| 742 format_string += '%(upstream:track)' |
| 743 |
| 744 info_map = {} |
| 745 data = run('for-each-ref', format_string, 'refs/heads') |
| 746 TrackingInfo = collections.namedtuple( |
| 747 'TrackingInfo', 'hash upstream ahead behind') |
| 748 for line in data.splitlines(): |
| 749 (branch, branch_hash, upstream_branch, tracking_status) = line.split(':') |
| 750 |
| 751 ahead_match = re.search(r'ahead (\d+)', tracking_status) |
| 752 ahead = int(ahead_match.group(1)) if ahead_match else None |
| 753 |
| 754 behind_match = re.search(r'behind (\d+)', tracking_status) |
| 755 behind = int(behind_match.group(1)) if behind_match else None |
| 756 |
| 757 info_map[branch] = TrackingInfo( |
| 758 hash=branch_hash, upstream=upstream_branch, ahead=ahead, behind=behind) |
| 759 |
| 760 # Set None for upstreams which are not branches (e.g empty upstream, remotes |
| 761 # and deleted upstream branches). |
| 762 missing_upstreams = {} |
| 763 for info in info_map.values(): |
| 764 if info.upstream not in info_map and info.upstream not in missing_upstreams: |
| 765 missing_upstreams[info.upstream] = None |
| 766 |
| 767 return dict(info_map.items() + missing_upstreams.items()) |
| OLD | NEW |