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 |