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 12 matching lines...) Expand all Loading... |
23 import os | 23 import os |
24 import re | 24 import re |
25 import signal | 25 import signal |
26 import sys | 26 import sys |
27 import tempfile | 27 import tempfile |
28 import textwrap | 28 import textwrap |
29 import threading | 29 import threading |
30 | 30 |
31 import subprocess2 | 31 import subprocess2 |
32 | 32 |
| 33 import git_cache |
| 34 |
33 | 35 |
34 GIT_EXE = 'git.bat' if sys.platform.startswith('win') else 'git' | 36 GIT_EXE = 'git.bat' if sys.platform.startswith('win') else 'git' |
35 TEST_MODE = False | 37 TEST_MODE = False |
36 | 38 |
37 FREEZE = 'FREEZE' | 39 FREEZE = 'FREEZE' |
38 FREEZE_SECTIONS = { | 40 FREEZE_SECTIONS = { |
39 'indexed': 'soft', | 41 'indexed': 'soft', |
40 'unindexed': 'mixed' | 42 'unindexed': 'mixed' |
41 } | 43 } |
42 FREEZE_MATCHER = re.compile(r'%s.(%s)' % (FREEZE, '|'.join(FREEZE_SECTIONS))) | 44 FREEZE_MATCHER = re.compile(r'%s.(%s)' % (FREEZE, '|'.join(FREEZE_SECTIONS))) |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
208 with self._dead_cond: | 210 with self._dead_cond: |
209 self._dead_cond.notifyAll() | 211 self._dead_cond.notifyAll() |
210 self._thread.join() | 212 self._thread.join() |
211 del self._thread | 213 del self._thread |
212 | 214 |
213 | 215 |
214 def once(function): | 216 def once(function): |
215 """@Decorates |function| so that it only performs its action once, no matter | 217 """@Decorates |function| so that it only performs its action once, no matter |
216 how many times the decorated |function| is called.""" | 218 how many times the decorated |function| is called.""" |
217 def _inner_gen(): | 219 def _inner_gen(): |
218 yield function() | 220 ret = function() |
| 221 yield ret |
219 while True: | 222 while True: |
220 yield | 223 yield ret |
221 return _inner_gen().next | 224 return _inner_gen().next |
222 | 225 |
223 | 226 |
224 ## Git functions | 227 ## Git functions |
225 | 228 |
226 | 229 |
227 def branch_config(branch, option, default=None): | 230 def branch_config(branch, option, default=None): |
228 return config('branch.%s.%s' % (branch, option), default=default) | 231 return config('branch.%s.%s' % (branch, option), default=default) |
229 | 232 |
230 | 233 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
268 | 271 |
269 def run_with_retcode(*cmd, **kwargs): | 272 def run_with_retcode(*cmd, **kwargs): |
270 """Run a command but only return the status code.""" | 273 """Run a command but only return the status code.""" |
271 try: | 274 try: |
272 run(*cmd, **kwargs) | 275 run(*cmd, **kwargs) |
273 return 0 | 276 return 0 |
274 except subprocess2.CalledProcessError as cpe: | 277 except subprocess2.CalledProcessError as cpe: |
275 return cpe.returncode | 278 return cpe.returncode |
276 | 279 |
277 | 280 |
| 281 def cached_fetch(commits): |
| 282 m = git_cache.Mirror.from_repo('.') |
| 283 if m: |
| 284 m.populate(fetch_specs=commits) |
| 285 else: |
| 286 for commit in commits: |
| 287 run('fetch', 'origin', commit) |
| 288 |
| 289 |
| 290 def check(*args, **kwargs): |
| 291 try: |
| 292 run(*args, **kwargs) |
| 293 return True |
| 294 except subprocess2.CalledProcessError: |
| 295 return False |
| 296 |
| 297 |
278 def config(option, default=None): | 298 def config(option, default=None): |
279 try: | 299 try: |
280 return run('config', '--get', option) or default | 300 return run('config', '--get', option) or default |
281 except subprocess2.CalledProcessError: | 301 except subprocess2.CalledProcessError: |
282 return default | 302 return default |
283 | 303 |
284 | 304 |
285 def config_list(option): | 305 def config_list(option): |
286 try: | 306 try: |
287 return run('config', '--get-all', option).split() | 307 return run('config', '--get-all', option).split() |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
368 else: | 388 else: |
369 logging.debug('Found pre-set merge-base for %s: %s', branch, base) | 389 logging.debug('Found pre-set merge-base for %s: %s', branch, base) |
370 | 390 |
371 if not base: | 391 if not base: |
372 base = actual_merge_base | 392 base = actual_merge_base |
373 manual_merge_base(branch, base) | 393 manual_merge_base(branch, base) |
374 | 394 |
375 return base | 395 return base |
376 | 396 |
377 | 397 |
| 398 def get_remote_url(remote): |
| 399 m = git_cache.Mirror.from_repo('.') |
| 400 if m: |
| 401 return m.url |
| 402 |
| 403 return config('remote.%s.url' % remote) |
| 404 |
| 405 |
378 def hash_multi(*reflike): | 406 def hash_multi(*reflike): |
379 return run('rev-parse', *reflike).splitlines() | 407 return run('rev-parse', *reflike).splitlines() |
380 | 408 |
381 | 409 |
382 def hash_one(reflike): | 410 def hash_one(reflike): |
383 return run('rev-parse', reflike) | 411 return run('rev-parse', reflike) |
384 | 412 |
385 | 413 |
386 def in_rebase(): | 414 def in_rebase(): |
387 git_dir = run('rev-parse', '--git-dir') | 415 git_dir = run('rev-parse', '--git-dir') |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 Returns (stdout, stderr) as a pair of strings. | 533 Returns (stdout, stderr) as a pair of strings. |
506 | 534 |
507 kwargs | 535 kwargs |
508 autostrip (bool) - Strip the output. Defaults to True. | 536 autostrip (bool) - Strip the output. Defaults to True. |
509 indata (str) - Specifies stdin data for the process. | 537 indata (str) - Specifies stdin data for the process. |
510 """ | 538 """ |
511 kwargs.setdefault('stdin', subprocess2.PIPE) | 539 kwargs.setdefault('stdin', subprocess2.PIPE) |
512 kwargs.setdefault('stdout', subprocess2.PIPE) | 540 kwargs.setdefault('stdout', subprocess2.PIPE) |
513 kwargs.setdefault('stderr', subprocess2.PIPE) | 541 kwargs.setdefault('stderr', subprocess2.PIPE) |
514 autostrip = kwargs.pop('autostrip', True) | 542 autostrip = kwargs.pop('autostrip', True) |
| 543 verbose = kwargs.pop('verbose', False) |
515 indata = kwargs.pop('indata', None) | 544 indata = kwargs.pop('indata', None) |
516 | 545 |
517 cmd = (GIT_EXE, '-c', 'color.ui=never') + cmd | 546 cmd = (GIT_EXE, '-c', 'color.ui=never') + cmd |
| 547 if verbose: |
| 548 print "running `%s`" % (cmd,) |
518 proc = subprocess2.Popen(cmd, **kwargs) | 549 proc = subprocess2.Popen(cmd, **kwargs) |
519 ret, err = proc.communicate(indata) | 550 ret, err = proc.communicate(indata) |
520 retcode = proc.wait() | 551 retcode = proc.wait() |
521 if retcode != 0: | 552 if retcode != 0: |
522 raise subprocess2.CalledProcessError(retcode, cmd, os.getcwd(), ret, err) | 553 raise subprocess2.CalledProcessError(retcode, cmd, os.getcwd(), ret, err) |
523 | 554 |
524 if autostrip: | 555 if autostrip: |
525 ret = (ret or '').strip() | 556 ret = (ret or '').strip() |
526 err = (err or '').strip() | 557 err = (err or '').strip() |
527 | 558 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
650 return None | 681 return None |
651 return ret | 682 return ret |
652 | 683 |
653 | 684 |
654 def upstream(branch): | 685 def upstream(branch): |
655 try: | 686 try: |
656 return run('rev-parse', '--abbrev-ref', '--symbolic-full-name', | 687 return run('rev-parse', '--abbrev-ref', '--symbolic-full-name', |
657 branch+'@{upstream}') | 688 branch+'@{upstream}') |
658 except subprocess2.CalledProcessError: | 689 except subprocess2.CalledProcessError: |
659 return None | 690 return None |
| 691 |
| 692 |
| 693 def verify_commit(commit): |
| 694 return check('rev-parse', '--quiet', '--verify', '%s^{commit}' % commit) |
OLD | NEW |