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 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
595 | 595 |
596 | 596 |
597 def set_branch_config(branch, option, value, scope='local'): | 597 def set_branch_config(branch, option, value, scope='local'): |
598 set_config('branch.%s.%s' % (branch, option), value, scope=scope) | 598 set_config('branch.%s.%s' % (branch, option), value, scope=scope) |
599 | 599 |
600 | 600 |
601 def set_config(option, value, scope='local'): | 601 def set_config(option, value, scope='local'): |
602 run('config', '--' + scope, option, value) | 602 run('config', '--' + scope, option, value) |
603 | 603 |
604 | 604 |
| 605 def get_dirty_files(): |
| 606 # Make sure index is up-to-date before running diff-index. |
| 607 run_with_retcode('update-index', '--refresh', '-q') |
| 608 return run('diff-index', '--name-status', 'HEAD') |
| 609 |
| 610 |
| 611 def is_dirty_git_tree(cmd): |
| 612 dirty = get_dirty_files() |
| 613 if dirty: |
| 614 print 'Cannot %s with a dirty tree. You must commit locally first.' % cmd |
| 615 print 'Uncommitted files: (git diff-index --name-status HEAD)' |
| 616 print dirty[:4096] |
| 617 if len(dirty) > 4096: # pragma: no cover |
| 618 print '... (run "git diff-index --name-status HEAD" to see full output).' |
| 619 return True |
| 620 return False |
| 621 |
| 622 |
605 def squash_current_branch(header=None, merge_base=None): | 623 def squash_current_branch(header=None, merge_base=None): |
606 header = header or 'git squash commit.' | 624 header = header or 'git squash commit.' |
607 merge_base = merge_base or get_or_create_merge_base(current_branch()) | 625 merge_base = merge_base or get_or_create_merge_base(current_branch()) |
608 log_msg = header + '\n' | 626 log_msg = header + '\n' |
609 if log_msg: | 627 if log_msg: |
610 log_msg += '\n' | 628 log_msg += '\n' |
611 log_msg += run('log', '--reverse', '--format=%H%n%B', '%s..HEAD' % merge_base) | 629 log_msg += run('log', '--reverse', '--format=%H%n%B', '%s..HEAD' % merge_base) |
612 run('reset', '--soft', merge_base) | 630 run('reset', '--soft', merge_base) |
| 631 |
| 632 if not get_dirty_files(): |
| 633 # Sometimes the squash can result in the same tree, meaning that there is |
| 634 # nothing to commit at this point. |
| 635 print 'Nothing to commit; squashed branch is empty' |
| 636 return False |
613 run('commit', '-a', '-F', '-', indata=log_msg) | 637 run('commit', '-a', '-F', '-', indata=log_msg) |
| 638 return True |
614 | 639 |
615 | 640 |
616 def tags(*args): | 641 def tags(*args): |
617 return run('tag', *args).splitlines() | 642 return run('tag', *args).splitlines() |
618 | 643 |
619 | 644 |
620 def thaw(): | 645 def thaw(): |
621 took_action = False | 646 took_action = False |
622 for sha in (s.strip() for s in run_stream('rev-list', 'HEAD').xreadlines()): | 647 for sha in (s.strip() for s in run_stream('rev-list', 'HEAD').xreadlines()): |
623 msg = run('show', '--format=%f%b', '-s', 'HEAD') | 648 msg = run('show', '--format=%f%b', '-s', 'HEAD') |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
762 hash=branch_hash, upstream=upstream_branch, ahead=ahead, behind=behind) | 787 hash=branch_hash, upstream=upstream_branch, ahead=ahead, behind=behind) |
763 | 788 |
764 # Set None for upstreams which are not branches (e.g empty upstream, remotes | 789 # Set None for upstreams which are not branches (e.g empty upstream, remotes |
765 # and deleted upstream branches). | 790 # and deleted upstream branches). |
766 missing_upstreams = {} | 791 missing_upstreams = {} |
767 for info in info_map.values(): | 792 for info in info_map.values(): |
768 if info.upstream not in info_map and info.upstream not in missing_upstreams: | 793 if info.upstream not in info_map and info.upstream not in missing_upstreams: |
769 missing_upstreams[info.upstream] = None | 794 missing_upstreams[info.upstream] = None |
770 | 795 |
771 return dict(info_map.items() + missing_upstreams.items()) | 796 return dict(info_map.items() + missing_upstreams.items()) |
OLD | NEW |