Chromium Code Reviews| 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 14 matching lines...) Expand all Loading... | |
| 25 import setup_color | 25 import setup_color |
| 26 import shutil | 26 import shutil |
| 27 import signal | 27 import signal |
| 28 import sys | 28 import sys |
| 29 import tempfile | 29 import tempfile |
| 30 import textwrap | 30 import textwrap |
| 31 import threading | 31 import threading |
| 32 | 32 |
| 33 import subprocess2 | 33 import subprocess2 |
| 34 | 34 |
| 35 from cStringIO import StringIO | |
| 36 | |
| 37 | |
| 35 ROOT = os.path.abspath(os.path.dirname(__file__)) | 38 ROOT = os.path.abspath(os.path.dirname(__file__)) |
| 36 | |
| 37 IS_WIN = sys.platform == 'win32' | 39 IS_WIN = sys.platform == 'win32' |
| 38 GIT_EXE = ROOT+'\\git.bat' if IS_WIN else 'git' | 40 GIT_EXE = ROOT+'\\git.bat' if IS_WIN else 'git' |
| 39 TEST_MODE = False | 41 TEST_MODE = False |
| 40 | 42 |
| 41 FREEZE = 'FREEZE' | 43 FREEZE = 'FREEZE' |
| 42 FREEZE_SECTIONS = { | 44 FREEZE_SECTIONS = { |
| 43 'indexed': 'soft', | 45 'indexed': 'soft', |
| 44 'unindexed': 'mixed' | 46 'unindexed': 'mixed' |
| 45 } | 47 } |
| 46 FREEZE_MATCHER = re.compile(r'%s.(%s)' % (FREEZE, '|'.join(FREEZE_SECTIONS))) | 48 FREEZE_MATCHER = re.compile(r'%s.(%s)' % (FREEZE, '|'.join(FREEZE_SECTIONS))) |
| (...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 382 except subprocess2.CalledProcessError: | 384 except subprocess2.CalledProcessError: |
| 383 pass | 385 pass |
| 384 | 386 |
| 385 | 387 |
| 386 def diff(oldrev, newrev, *args): | 388 def diff(oldrev, newrev, *args): |
| 387 return run('diff', oldrev, newrev, *args) | 389 return run('diff', oldrev, newrev, *args) |
| 388 | 390 |
| 389 | 391 |
| 390 def freeze(): | 392 def freeze(): |
| 391 took_action = False | 393 took_action = False |
| 394 key = 'depot-tools.freeze-size-limit' | |
| 395 MB = 2**20 | |
| 396 limit_mb = get_config_int(key, 100) | |
| 397 untracked_size = 0 | |
| 398 | |
| 399 for f, s in status(): | |
| 400 if is_unmerged(s): | |
| 401 die("Cannot freeze unmerged changes!") | |
| 402 if limit_mb > 0: | |
| 403 if s.lstat == '?': | |
| 404 untracked_size += os.stat(f).st_size / MB | |
|
tandrii(chromium)
2016/06/21 14:43:37
don't divide here, otherwise 3 files 400KB each wi
agable
2016/06/22 11:16:51
Done
| |
| 405 if untracked_size > limit_mb: | |
|
tandrii(chromium)
2016/06/21 14:43:37
divide by MB here, and better yet multiply by limi
agable
2016/06/22 11:16:51
Done
| |
| 406 die("""\ | |
| 407 You appear to have too much untracked+unignored data in your git | |
| 408 checkout: %d/%dMB. | |
|
tandrii(chromium)
2016/06/21 14:43:37
personal preference: s/%d/%.1f and make MB a float
agable
2016/06/22 11:16:51
Gonna leave limit in MB, since letting it be a dec
| |
| 409 | |
| 410 Run `git status` to see what it is. | |
| 411 | |
| 412 In addition to making many git commands slower, this will prevent | |
| 413 depot_tools from freezing your in-progress changes. | |
| 414 | |
| 415 You should add untracked data that you want to ignore to your repo's | |
| 416 .git/info/excludes | |
| 417 file. See `git help ignore` for the format of this file. | |
| 418 | |
| 419 If this data is indended as part of your commit, you may adjust the | |
| 420 freeze limit by running: | |
| 421 git config %s <new_limit> | |
| 422 Where <new_limit> is an integer threshold in megabytes.""", | |
| 423 untracked_size, limit_mb, key) | |
| 392 | 424 |
| 393 try: | 425 try: |
| 394 run('commit', '--no-verify', '-m', FREEZE + '.indexed') | 426 run('commit', '--no-verify', '-m', FREEZE + '.indexed') |
| 395 took_action = True | 427 took_action = True |
| 396 except subprocess2.CalledProcessError: | 428 except subprocess2.CalledProcessError: |
| 397 pass | 429 pass |
| 398 | 430 |
| 399 try: | 431 try: |
| 400 run('add', '-A') | 432 run('add', '-A') |
| 401 run('commit', '--no-verify', '-m', FREEZE + '.unindexed') | 433 run('commit', '--no-verify', '-m', FREEZE + '.unindexed') |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 492 ret = run('hash-object', '-t', kind, '-w', '--stdin', stdin=f) | 524 ret = run('hash-object', '-t', kind, '-w', '--stdin', stdin=f) |
| 493 f.close() | 525 f.close() |
| 494 return ret | 526 return ret |
| 495 | 527 |
| 496 | 528 |
| 497 def is_dormant(branch): | 529 def is_dormant(branch): |
| 498 # TODO(iannucci): Do an oldness check? | 530 # TODO(iannucci): Do an oldness check? |
| 499 return branch_config(branch, 'dormant', 'false') != 'false' | 531 return branch_config(branch, 'dormant', 'false') != 'false' |
| 500 | 532 |
| 501 | 533 |
| 534 def is_unmerged(stat_value): | |
| 535 return ( | |
| 536 'U' in (stat_value.lstat, stat_value.rstat) or | |
| 537 ((stat_value.lstat == stat_value.rstat) and stat_value.lstat in 'AD') | |
| 538 ) | |
| 539 | |
| 540 | |
| 502 def manual_merge_base(branch, base, parent): | 541 def manual_merge_base(branch, base, parent): |
| 503 set_branch_config(branch, 'base', base) | 542 set_branch_config(branch, 'base', base) |
| 504 set_branch_config(branch, 'base-upstream', parent) | 543 set_branch_config(branch, 'base-upstream', parent) |
| 505 | 544 |
| 506 | 545 |
| 507 def mktree(treedict): | 546 def mktree(treedict): |
| 508 """Makes a git tree object and returns its hash. | 547 """Makes a git tree object and returns its hash. |
| 509 | 548 |
| 510 See |tree()| for the values of mode, type, and ref. | 549 See |tree()| for the values of mode, type, and ref. |
| 511 | 550 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 701 if dirty: | 740 if dirty: |
| 702 print 'Cannot %s with a dirty tree. You must commit locally first.' % cmd | 741 print 'Cannot %s with a dirty tree. You must commit locally first.' % cmd |
| 703 print 'Uncommitted files: (git diff-index --name-status HEAD)' | 742 print 'Uncommitted files: (git diff-index --name-status HEAD)' |
| 704 print dirty[:4096] | 743 print dirty[:4096] |
| 705 if len(dirty) > 4096: # pragma: no cover | 744 if len(dirty) > 4096: # pragma: no cover |
| 706 print '... (run "git diff-index --name-status HEAD" to see full output).' | 745 print '... (run "git diff-index --name-status HEAD" to see full output).' |
| 707 return True | 746 return True |
| 708 return False | 747 return False |
| 709 | 748 |
| 710 | 749 |
| 750 def status(): | |
| 751 """Returns a parsed version of git-status. | |
| 752 | |
| 753 Returns a generator of (current_name, (lstat, rstat, src)) pairs where: | |
| 754 * current_name is the name of the file | |
| 755 * lstat is the left status code letter from git-status | |
| 756 * rstat is the left status code letter from git-status | |
| 757 * src is the current name of the file, or the original name of the file | |
| 758 if lstat == 'R' | |
| 759 """ | |
| 760 stat_entry = collections.namedtuple('stat_entry', 'lstat rstat src') | |
| 761 | |
| 762 def tokenizer(stream): | |
| 763 acc = StringIO() | |
| 764 c = None | |
| 765 while c != '': | |
| 766 c = stream.read(1) | |
| 767 if c in (None, '', '\0'): | |
| 768 s = acc.getvalue() | |
|
tandrii(chromium)
2016/06/21 14:43:37
nit: if you'd had used plain StringIO, which for t
agable
2016/06/22 11:16:51
Good point, done.
| |
| 769 acc = StringIO() | |
| 770 if s: | |
| 771 yield s | |
| 772 else: | |
| 773 acc.write(c) | |
| 774 | |
| 775 def parser(tokens): | |
| 776 END = object() | |
| 777 tok = lambda: next(tokens, END) | |
| 778 while True: | |
| 779 status_dest = tok() | |
| 780 if status_dest is END: | |
| 781 return | |
| 782 stat, dest = status_dest[:2], status_dest[3:] | |
|
tandrii(chromium)
2016/06/21 14:43:37
suggestion: why not plain old except to detect END
agable
2016/06/22 11:16:51
Nice, done.
| |
| 783 lstat, rstat = stat | |
| 784 if lstat == 'R': | |
| 785 src = tok() | |
| 786 assert src is not END | |
| 787 else: | |
| 788 src = dest | |
| 789 yield (dest, stat_entry(lstat, rstat, src)) | |
| 790 | |
| 791 return parser(tokenizer(run_stream('status', '-z', bufsize=-1))) | |
| 792 | |
| 793 | |
| 711 def squash_current_branch(header=None, merge_base=None): | 794 def squash_current_branch(header=None, merge_base=None): |
| 712 header = header or 'git squash commit.' | 795 header = header or 'git squash commit.' |
| 713 merge_base = merge_base or get_or_create_merge_base(current_branch()) | 796 merge_base = merge_base or get_or_create_merge_base(current_branch()) |
| 714 log_msg = header + '\n' | 797 log_msg = header + '\n' |
| 715 if log_msg: | 798 if log_msg: |
| 716 log_msg += '\n' | 799 log_msg += '\n' |
| 717 log_msg += run('log', '--reverse', '--format=%H%n%B', '%s..HEAD' % merge_base) | 800 log_msg += run('log', '--reverse', '--format=%H%n%B', '%s..HEAD' % merge_base) |
| 718 run('reset', '--soft', merge_base) | 801 run('reset', '--soft', merge_base) |
| 719 | 802 |
| 720 if not get_dirty_files(): | 803 if not get_dirty_files(): |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 912 ['HEAD']) | 995 ['HEAD']) |
| 913 | 996 |
| 914 | 997 |
| 915 def clone_file(repository, new_workdir, link, operation): | 998 def clone_file(repository, new_workdir, link, operation): |
| 916 if not os.path.exists(os.path.join(repository, link)): | 999 if not os.path.exists(os.path.join(repository, link)): |
| 917 return | 1000 return |
| 918 link_dir = os.path.dirname(os.path.join(new_workdir, link)) | 1001 link_dir = os.path.dirname(os.path.join(new_workdir, link)) |
| 919 if not os.path.exists(link_dir): | 1002 if not os.path.exists(link_dir): |
| 920 os.makedirs(link_dir) | 1003 os.makedirs(link_dir) |
| 921 operation(os.path.join(repository, link), os.path.join(new_workdir, link)) | 1004 operation(os.path.join(repository, link), os.path.join(new_workdir, link)) |
| OLD | NEW |