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 if get_git_version() >= MIN_UPSTREAM_TRACK_GIT_VERSION: | |
740 format_string += '%(upstream:track)' | |
741 | |
742 info_map = {} | |
743 data = run('for-each-ref', format_string, 'refs/heads') | |
744 TrackingInfo = collections.namedtuple( | |
745 'TrackingInfo', 'hash upstream ahead behind') | |
746 for line in data.splitlines(): | |
747 (branch, branch_hash, upstream_branch, tracking_status) = line.split(':') | |
748 | |
749 ahead_match = re.search(r'ahead (\d+)', tracking_status) | |
750 ahead = int(ahead_match.group(1)) if ahead_match else None | |
751 | |
752 behind_match = re.search(r'behind (\d+)', tracking_status) | |
753 behind = int(behind_match.group(1)) if behind_match else None | |
754 | |
755 info_map[branch] = TrackingInfo( | |
756 hash=branch_hash, upstream=upstream_branch, ahead=ahead, behind=behind) | |
757 | |
758 empty_info = TrackingInfo(hash=None, upstream=None, ahead=None, behind=None) | |
759 | |
760 # Set an empty info object for upstreams which are not branches (e.g empty | |
761 # upstream, remotes 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] = empty_info | |
iannucci
2014/09/02 22:31:27
Maybe this is more convenient in the user-code (I
calamity
2014/09/03 01:43:21
Done.
| |
766 | |
767 return dict(info_map.items() + missing_upstreams.items()) | |
OLD | NEW |