Chromium Code Reviews| Index: git_common.py |
| diff --git a/git_common.py b/git_common.py |
| index 6abb5bad0b7f20a50baa4f84012155b965cc3b70..d9ad7ce8608e6e19f93b28e66095169d973334c0 100644 |
| --- a/git_common.py |
| +++ b/git_common.py |
| @@ -32,8 +32,10 @@ import threading |
| import subprocess2 |
| -ROOT = os.path.abspath(os.path.dirname(__file__)) |
| +from cStringIO import StringIO |
| + |
| +ROOT = os.path.abspath(os.path.dirname(__file__)) |
| IS_WIN = sys.platform == 'win32' |
| GIT_EXE = ROOT+'\\git.bat' if IS_WIN else 'git' |
| TEST_MODE = False |
| @@ -389,6 +391,36 @@ def diff(oldrev, newrev, *args): |
| def freeze(): |
| took_action = False |
| + key = 'depot-tools.freeze-size-limit' |
| + MB = 2**20 |
| + limit_mb = get_config_int(key, 100) |
| + untracked_size = 0 |
| + |
| + for f, s in status(): |
| + if is_unmerged(s): |
| + die("Cannot freeze unmerged changes!") |
| + if limit_mb > 0: |
| + if s.lstat == '?': |
| + 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
|
| + 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
|
| + die("""\ |
| + You appear to have too much untracked+unignored data in your git |
| + 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
|
| + |
| + Run `git status` to see what it is. |
| + |
| + In addition to making many git commands slower, this will prevent |
| + depot_tools from freezing your in-progress changes. |
| + |
| + You should add untracked data that you want to ignore to your repo's |
| + .git/info/excludes |
| + file. See `git help ignore` for the format of this file. |
| + |
| + If this data is indended as part of your commit, you may adjust the |
| + freeze limit by running: |
| + git config %s <new_limit> |
| + Where <new_limit> is an integer threshold in megabytes.""", |
| + untracked_size, limit_mb, key) |
| try: |
| run('commit', '--no-verify', '-m', FREEZE + '.indexed') |
| @@ -499,6 +531,13 @@ def is_dormant(branch): |
| return branch_config(branch, 'dormant', 'false') != 'false' |
| +def is_unmerged(stat_value): |
| + return ( |
| + 'U' in (stat_value.lstat, stat_value.rstat) or |
| + ((stat_value.lstat == stat_value.rstat) and stat_value.lstat in 'AD') |
| + ) |
| + |
| + |
| def manual_merge_base(branch, base, parent): |
| set_branch_config(branch, 'base', base) |
| set_branch_config(branch, 'base-upstream', parent) |
| @@ -708,6 +747,50 @@ def is_dirty_git_tree(cmd): |
| return False |
| +def status(): |
| + """Returns a parsed version of git-status. |
| + |
| + Returns a generator of (current_name, (lstat, rstat, src)) pairs where: |
| + * current_name is the name of the file |
| + * lstat is the left status code letter from git-status |
| + * rstat is the left status code letter from git-status |
| + * src is the current name of the file, or the original name of the file |
| + if lstat == 'R' |
| + """ |
| + stat_entry = collections.namedtuple('stat_entry', 'lstat rstat src') |
| + |
| + def tokenizer(stream): |
| + acc = StringIO() |
| + c = None |
| + while c != '': |
| + c = stream.read(1) |
| + if c in (None, '', '\0'): |
| + 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.
|
| + acc = StringIO() |
| + if s: |
| + yield s |
| + else: |
| + acc.write(c) |
| + |
| + def parser(tokens): |
| + END = object() |
| + tok = lambda: next(tokens, END) |
| + while True: |
| + status_dest = tok() |
| + if status_dest is END: |
| + return |
| + 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.
|
| + lstat, rstat = stat |
| + if lstat == 'R': |
| + src = tok() |
| + assert src is not END |
| + else: |
| + src = dest |
| + yield (dest, stat_entry(lstat, rstat, src)) |
| + |
| + return parser(tokenizer(run_stream('status', '-z', bufsize=-1))) |
| + |
| + |
| def squash_current_branch(header=None, merge_base=None): |
| header = header or 'git squash commit.' |
| merge_base = merge_base or get_or_create_merge_base(current_branch()) |