Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(851)

Side by Side Diff: git_cl.py

Issue 1075723002: Extract authentication options handling into a separate function. (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « git_cherry_pick_upload.py ('k') | my_activity.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 # Copyright (C) 2008 Evan Martin <martine@danga.com> 6 # Copyright (C) 2008 Evan Martin <martine@danga.com>
7 7
8 """A git-command for integrating reviews on Rietveld.""" 8 """A git-command for integrating reviews on Rietveld."""
9 9
10 from distutils.version import LooseVersion 10 from distutils.version import LooseVersion
(...skipping 16 matching lines...) Expand all
27 import zlib 27 import zlib
28 28
29 try: 29 try:
30 import readline # pylint: disable=F0401,W0611 30 import readline # pylint: disable=F0401,W0611
31 except ImportError: 31 except ImportError:
32 pass 32 pass
33 33
34 34
35 from third_party import colorama 35 from third_party import colorama
36 from third_party import upload 36 from third_party import upload
37 import auth
37 import breakpad # pylint: disable=W0611 38 import breakpad # pylint: disable=W0611
38 import clang_format 39 import clang_format
39 import dart_format 40 import dart_format
40 import fix_encoding 41 import fix_encoding
41 import gclient_utils 42 import gclient_utils
42 import git_common 43 import git_common
43 import owners 44 import owners
44 import owners_finder 45 import owners_finder
45 import presubmit_support 46 import presubmit_support
46 import rietveld 47 import rietveld
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 self.LazyUpdateIfNeeded() 492 self.LazyUpdateIfNeeded()
492 return RunGit(['config', param], **kwargs).strip() 493 return RunGit(['config', param], **kwargs).strip()
493 494
494 495
495 def ShortBranchName(branch): 496 def ShortBranchName(branch):
496 """Convert a name like 'refs/heads/foo' to just 'foo'.""" 497 """Convert a name like 'refs/heads/foo' to just 'foo'."""
497 return branch.replace('refs/heads/', '') 498 return branch.replace('refs/heads/', '')
498 499
499 500
500 class Changelist(object): 501 class Changelist(object):
501 def __init__(self, branchref=None, issue=None): 502 def __init__(self, branchref=None, issue=None, auth_config=None):
502 # Poke settings so we get the "configure your server" message if necessary. 503 # Poke settings so we get the "configure your server" message if necessary.
503 global settings 504 global settings
504 if not settings: 505 if not settings:
505 # Happens when git_cl.py is used as a utility library. 506 # Happens when git_cl.py is used as a utility library.
506 settings = Settings() 507 settings = Settings()
507 settings.GetDefaultServerUrl() 508 settings.GetDefaultServerUrl()
508 self.branchref = branchref 509 self.branchref = branchref
509 if self.branchref: 510 if self.branchref:
510 self.branch = ShortBranchName(self.branchref) 511 self.branch = ShortBranchName(self.branchref)
511 else: 512 else:
512 self.branch = None 513 self.branch = None
513 self.rietveld_server = None 514 self.rietveld_server = None
514 self.upstream_branch = None 515 self.upstream_branch = None
515 self.lookedup_issue = False 516 self.lookedup_issue = False
516 self.issue = issue or None 517 self.issue = issue or None
517 self.has_description = False 518 self.has_description = False
518 self.description = None 519 self.description = None
519 self.lookedup_patchset = False 520 self.lookedup_patchset = False
520 self.patchset = None 521 self.patchset = None
521 self._rpc_server = None
522 self.cc = None 522 self.cc = None
523 self.watchers = () 523 self.watchers = ()
524 self._auth_config = auth_config
525 self._props = None
524 self._remote = None 526 self._remote = None
525 self._props = None 527 self._rpc_server = None
528
529 @property
530 def auth_config(self):
531 return self._auth_config
526 532
527 def GetCCList(self): 533 def GetCCList(self):
528 """Return the users cc'd on this CL. 534 """Return the users cc'd on this CL.
529 535
530 Return is a string suitable for passing to gcl with the --cc flag. 536 Return is a string suitable for passing to gcl with the --cc flag.
531 """ 537 """
532 if self.cc is None: 538 if self.cc is None:
533 base_cc = settings.GetDefaultCCList() 539 base_cc = settings.GetDefaultCCList()
534 more_cc = ','.join(self.watchers) 540 more_cc = ','.join(self.watchers)
535 self.cc = ','.join(filter(None, (base_cc, more_cc))) or '' 541 self.cc = ','.join(filter(None, (base_cc, more_cc))) or ''
(...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 DieWithError( 984 DieWithError(
979 ('Access denied to issue %s. Maybe the patchset %s doesn\'t ' 985 ('Access denied to issue %s. Maybe the patchset %s doesn\'t '
980 'match?') % (self.GetIssue(), self.GetPatchset())) 986 'match?') % (self.GetIssue(), self.GetPatchset()))
981 raise 987 raise
982 988
983 def RpcServer(self): 989 def RpcServer(self):
984 """Returns an upload.RpcServer() to access this review's rietveld instance. 990 """Returns an upload.RpcServer() to access this review's rietveld instance.
985 """ 991 """
986 if not self._rpc_server: 992 if not self._rpc_server:
987 self._rpc_server = rietveld.CachingRietveld( 993 self._rpc_server = rietveld.CachingRietveld(
988 self.GetRietveldServer(), None, None) 994 self.GetRietveldServer(),
995 self._auth_config or auth.make_auth_config())
989 return self._rpc_server 996 return self._rpc_server
990 997
991 def _IssueSetting(self): 998 def _IssueSetting(self):
992 """Return the git setting that stores this change's issue.""" 999 """Return the git setting that stores this change's issue."""
993 return 'branch.%s.rietveldissue' % self.GetBranch() 1000 return 'branch.%s.rietveldissue' % self.GetBranch()
994 1001
995 def _PatchsetSetting(self): 1002 def _PatchsetSetting(self):
996 """Return the git setting that stores this change's most recent patchset.""" 1003 """Return the git setting that stores this change's most recent patchset."""
997 return 'branch.%s.rietveldpatchset' % self.GetBranch() 1004 return 'branch.%s.rietveldpatchset' % self.GetBranch()
998 1005
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
1335 return { 1342 return {
1336 'unsent': Fore.RED, 1343 'unsent': Fore.RED,
1337 'waiting': Fore.BLUE, 1344 'waiting': Fore.BLUE,
1338 'reply': Fore.YELLOW, 1345 'reply': Fore.YELLOW,
1339 'lgtm': Fore.GREEN, 1346 'lgtm': Fore.GREEN,
1340 'commit': Fore.MAGENTA, 1347 'commit': Fore.MAGENTA,
1341 'closed': Fore.CYAN, 1348 'closed': Fore.CYAN,
1342 'error': Fore.WHITE, 1349 'error': Fore.WHITE,
1343 }.get(status, Fore.WHITE) 1350 }.get(status, Fore.WHITE)
1344 1351
1345 def fetch_cl_status(b): 1352 def fetch_cl_status(b, auth_config=None):
1346 """Fetches information for an issue and returns (branch, issue, color).""" 1353 """Fetches information for an issue and returns (branch, issue, color)."""
1347 c = Changelist(branchref=b) 1354 c = Changelist(branchref=b, auth_config=auth_config)
1348 i = c.GetIssueURL() 1355 i = c.GetIssueURL()
1349 status = c.GetStatus() 1356 status = c.GetStatus()
1350 color = color_for_status(status) 1357 color = color_for_status(status)
1351 1358
1352 if i and (not status or status == 'error'): 1359 if i and (not status or status == 'error'):
1353 # The issue probably doesn't exist anymore. 1360 # The issue probably doesn't exist anymore.
1354 i += ' (broken)' 1361 i += ' (broken)'
1355 1362
1356 return (b, i, color) 1363 return (b, i, color)
1357 1364
1358 def get_cl_statuses(branches, fine_grained, max_processes=None): 1365 def get_cl_statuses(
1366 branches, fine_grained, max_processes=None, auth_config=None):
1359 """Returns a blocking iterable of (branch, issue, color) for given branches. 1367 """Returns a blocking iterable of (branch, issue, color) for given branches.
1360 1368
1361 If fine_grained is true, this will fetch CL statuses from the server. 1369 If fine_grained is true, this will fetch CL statuses from the server.
1362 Otherwise, simply indicate if there's a matching url for the given branches. 1370 Otherwise, simply indicate if there's a matching url for the given branches.
1363 1371
1364 If max_processes is specified, it is used as the maximum number of processes 1372 If max_processes is specified, it is used as the maximum number of processes
1365 to spawn to fetch CL status from the server. Otherwise 1 process per branch is 1373 to spawn to fetch CL status from the server. Otherwise 1 process per branch is
1366 spawned. 1374 spawned.
1367 """ 1375 """
1368 # Silence upload.py otherwise it becomes unwieldly. 1376 # Silence upload.py otherwise it becomes unwieldly.
1369 upload.verbosity = 0 1377 upload.verbosity = 0
1370 1378
1371 if fine_grained: 1379 if fine_grained:
1372 # Process one branch synchronously to work through authentication, then 1380 # Process one branch synchronously to work through authentication, then
1373 # spawn processes to process all the other branches in parallel. 1381 # spawn processes to process all the other branches in parallel.
1374 if branches: 1382 if branches:
1375 yield fetch_cl_status(branches[0]) 1383 fetch = lambda branch: fetch_cl_status(branch, auth_config=auth_config)
1384 yield fetch(branches[0])
1376 1385
1377 branches_to_fetch = branches[1:] 1386 branches_to_fetch = branches[1:]
1378 pool = ThreadPool( 1387 pool = ThreadPool(
1379 min(max_processes, len(branches_to_fetch)) 1388 min(max_processes, len(branches_to_fetch))
1380 if max_processes is not None 1389 if max_processes is not None
1381 else len(branches_to_fetch)) 1390 else len(branches_to_fetch))
1382 for x in pool.imap_unordered(fetch_cl_status, branches_to_fetch): 1391 for x in pool.imap_unordered(fetch, branches_to_fetch):
1383 yield x 1392 yield x
1384 else: 1393 else:
1385 # Do not use GetApprovingReviewers(), since it requires an HTTP request. 1394 # Do not use GetApprovingReviewers(), since it requires an HTTP request.
1386 for b in branches: 1395 for b in branches:
1387 c = Changelist(branchref=b) 1396 c = Changelist(branchref=b, auth_config=auth_config)
1388 url = c.GetIssueURL() 1397 url = c.GetIssueURL()
1389 yield (b, url, Fore.BLUE if url else Fore.WHITE) 1398 yield (b, url, Fore.BLUE if url else Fore.WHITE)
1390 1399
1391 def CMDstatus(parser, args): 1400 def CMDstatus(parser, args):
1392 """Show status of changelists. 1401 """Show status of changelists.
1393 1402
1394 Colors are used to tell the state of the CL unless --fast is used: 1403 Colors are used to tell the state of the CL unless --fast is used:
1395 - Red not sent for review or broken 1404 - Red not sent for review or broken
1396 - Blue waiting for review 1405 - Blue waiting for review
1397 - Yellow waiting for you to reply to review 1406 - Yellow waiting for you to reply to review
1398 - Green LGTM'ed 1407 - Green LGTM'ed
1399 - Magenta in the commit queue 1408 - Magenta in the commit queue
1400 - Cyan was committed, branch can be deleted 1409 - Cyan was committed, branch can be deleted
1401 1410
1402 Also see 'git cl comments'. 1411 Also see 'git cl comments'.
1403 """ 1412 """
1404 parser.add_option('--field', 1413 parser.add_option('--field',
1405 help='print only specific field (desc|id|patch|url)') 1414 help='print only specific field (desc|id|patch|url)')
1406 parser.add_option('-f', '--fast', action='store_true', 1415 parser.add_option('-f', '--fast', action='store_true',
1407 help='Do not retrieve review status') 1416 help='Do not retrieve review status')
1408 parser.add_option( 1417 parser.add_option(
1409 '-j', '--maxjobs', action='store', type=int, 1418 '-j', '--maxjobs', action='store', type=int,
1410 help='The maximum number of jobs to use when retrieving review status') 1419 help='The maximum number of jobs to use when retrieving review status')
1411 (options, args) = parser.parse_args(args) 1420
1421 auth.add_auth_options(parser)
1422 options, args = parser.parse_args(args)
1412 if args: 1423 if args:
1413 parser.error('Unsupported args: %s' % args) 1424 parser.error('Unsupported args: %s' % args)
1425 auth_config = auth.extract_auth_config_from_options(options)
1414 1426
1415 if options.field: 1427 if options.field:
1416 cl = Changelist() 1428 cl = Changelist(auth_config=auth_config)
1417 if options.field.startswith('desc'): 1429 if options.field.startswith('desc'):
1418 print cl.GetDescription() 1430 print cl.GetDescription()
1419 elif options.field == 'id': 1431 elif options.field == 'id':
1420 issueid = cl.GetIssue() 1432 issueid = cl.GetIssue()
1421 if issueid: 1433 if issueid:
1422 print issueid 1434 print issueid
1423 elif options.field == 'patch': 1435 elif options.field == 'patch':
1424 patchset = cl.GetPatchset() 1436 patchset = cl.GetPatchset()
1425 if patchset: 1437 if patchset:
1426 print patchset 1438 print patchset
1427 elif options.field == 'url': 1439 elif options.field == 'url':
1428 url = cl.GetIssueURL() 1440 url = cl.GetIssueURL()
1429 if url: 1441 if url:
1430 print url 1442 print url
1431 return 0 1443 return 0
1432 1444
1433 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads']) 1445 branches = RunGit(['for-each-ref', '--format=%(refname)', 'refs/heads'])
1434 if not branches: 1446 if not branches:
1435 print('No local branch found.') 1447 print('No local branch found.')
1436 return 0 1448 return 0
1437 1449
1438 changes = (Changelist(branchref=b) for b in branches.splitlines()) 1450 changes = (
1451 Changelist(branchref=b, auth_config=auth_config)
1452 for b in branches.splitlines())
1439 branches = [c.GetBranch() for c in changes] 1453 branches = [c.GetBranch() for c in changes]
1440 alignment = max(5, max(len(b) for b in branches)) 1454 alignment = max(5, max(len(b) for b in branches))
1441 print 'Branches associated with reviews:' 1455 print 'Branches associated with reviews:'
1442 output = get_cl_statuses(branches, 1456 output = get_cl_statuses(branches,
1443 fine_grained=not options.fast, 1457 fine_grained=not options.fast,
1444 max_processes=options.maxjobs) 1458 max_processes=options.maxjobs,
1459 auth_config=auth_config)
1445 1460
1446 branch_statuses = {} 1461 branch_statuses = {}
1447 alignment = max(5, max(len(ShortBranchName(b)) for b in branches)) 1462 alignment = max(5, max(len(ShortBranchName(b)) for b in branches))
1448 for branch in sorted(branches): 1463 for branch in sorted(branches):
1449 while branch not in branch_statuses: 1464 while branch not in branch_statuses:
1450 b, i, color = output.next() 1465 b, i, color = output.next()
1451 branch_statuses[b] = (i, color) 1466 branch_statuses[b] = (i, color)
1452 issue, color = branch_statuses.pop(branch) 1467 issue, color = branch_statuses.pop(branch)
1453 reset = Fore.RESET 1468 reset = Fore.RESET
1454 if not sys.stdout.isatty(): 1469 if not sys.stdout.isatty():
1455 color = '' 1470 color = ''
1456 reset = '' 1471 reset = ''
1457 print ' %*s : %s%s%s' % ( 1472 print ' %*s : %s%s%s' % (
1458 alignment, ShortBranchName(branch), color, issue, reset) 1473 alignment, ShortBranchName(branch), color, issue, reset)
1459 1474
1460 cl = Changelist() 1475 cl = Changelist(auth_config=auth_config)
1461 print 1476 print
1462 print 'Current branch:', 1477 print 'Current branch:',
1463 if not cl.GetIssue(): 1478 if not cl.GetIssue():
1464 print 'no issue assigned.' 1479 print 'no issue assigned.'
1465 return 0 1480 return 0
1466 print cl.GetBranch() 1481 print cl.GetBranch()
1467 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) 1482 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL())
1468 if not options.fast: 1483 if not options.fast:
1469 print 'Issue description:' 1484 print 'Issue description:'
1470 print cl.GetDescription(pretty=True) 1485 print cl.GetDescription(pretty=True)
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1527 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL()) 1542 print 'Issue number: %s (%s)' % (cl.GetIssue(), cl.GetIssueURL())
1528 return 0 1543 return 0
1529 1544
1530 1545
1531 def CMDcomments(parser, args): 1546 def CMDcomments(parser, args):
1532 """Shows or posts review comments for any changelist.""" 1547 """Shows or posts review comments for any changelist."""
1533 parser.add_option('-a', '--add-comment', dest='comment', 1548 parser.add_option('-a', '--add-comment', dest='comment',
1534 help='comment to add to an issue') 1549 help='comment to add to an issue')
1535 parser.add_option('-i', dest='issue', 1550 parser.add_option('-i', dest='issue',
1536 help="review issue id (defaults to current issue)") 1551 help="review issue id (defaults to current issue)")
1552 auth.add_auth_options(parser)
1537 options, args = parser.parse_args(args) 1553 options, args = parser.parse_args(args)
1554 auth_config = auth.extract_auth_config_from_options(options)
1538 1555
1539 issue = None 1556 issue = None
1540 if options.issue: 1557 if options.issue:
1541 try: 1558 try:
1542 issue = int(options.issue) 1559 issue = int(options.issue)
1543 except ValueError: 1560 except ValueError:
1544 DieWithError('A review issue id is expected to be a number') 1561 DieWithError('A review issue id is expected to be a number')
1545 1562
1546 cl = Changelist(issue=issue) 1563 cl = Changelist(issue=issue, auth_config=auth_config)
1547 1564
1548 if options.comment: 1565 if options.comment:
1549 cl.AddComment(options.comment) 1566 cl.AddComment(options.comment)
1550 return 0 1567 return 0
1551 1568
1552 data = cl.GetIssueProperties() 1569 data = cl.GetIssueProperties()
1553 for message in sorted(data.get('messages', []), key=lambda x: x['date']): 1570 for message in sorted(data.get('messages', []), key=lambda x: x['date']):
1554 if message['disapproval']: 1571 if message['disapproval']:
1555 color = Fore.RED 1572 color = Fore.RED
1556 elif message['approval']: 1573 elif message['approval']:
1557 color = Fore.GREEN 1574 color = Fore.GREEN
1558 elif message['sender'] == data['owner_email']: 1575 elif message['sender'] == data['owner_email']:
1559 color = Fore.MAGENTA 1576 color = Fore.MAGENTA
1560 else: 1577 else:
1561 color = Fore.BLUE 1578 color = Fore.BLUE
1562 print '\n%s%s %s%s' % ( 1579 print '\n%s%s %s%s' % (
1563 color, message['date'].split('.', 1)[0], message['sender'], 1580 color, message['date'].split('.', 1)[0], message['sender'],
1564 Fore.RESET) 1581 Fore.RESET)
1565 if message['text'].strip(): 1582 if message['text'].strip():
1566 print '\n'.join(' ' + l for l in message['text'].splitlines()) 1583 print '\n'.join(' ' + l for l in message['text'].splitlines())
1567 return 0 1584 return 0
1568 1585
1569 1586
1570 def CMDdescription(parser, args): 1587 def CMDdescription(parser, args):
1571 """Brings up the editor for the current CL's description.""" 1588 """Brings up the editor for the current CL's description."""
1572 parser.parse_args(args) 1589 auth.add_auth_options(parser)
1573 cl = Changelist() 1590 options, _ = parser.parse_args(args)
1591 auth_config = auth.extract_auth_config_from_options(options)
1592 cl = Changelist(auth_config=auth_config)
1574 if not cl.GetIssue(): 1593 if not cl.GetIssue():
1575 DieWithError('This branch has no associated changelist.') 1594 DieWithError('This branch has no associated changelist.')
1576 description = ChangeDescription(cl.GetDescription()) 1595 description = ChangeDescription(cl.GetDescription())
1577 description.prompt() 1596 description.prompt()
1578 if cl.GetDescription() != description.description: 1597 if cl.GetDescription() != description.description:
1579 cl.UpdateDescription(description.description) 1598 cl.UpdateDescription(description.description)
1580 return 0 1599 return 0
1581 1600
1582 1601
1583 def CreateDescriptionFromLog(args): 1602 def CreateDescriptionFromLog(args):
1584 """Pulls out the commit log to use as a base for the CL description.""" 1603 """Pulls out the commit log to use as a base for the CL description."""
1585 log_args = [] 1604 log_args = []
1586 if len(args) == 1 and not args[0].endswith('.'): 1605 if len(args) == 1 and not args[0].endswith('.'):
1587 log_args = [args[0] + '..'] 1606 log_args = [args[0] + '..']
1588 elif len(args) == 1 and args[0].endswith('...'): 1607 elif len(args) == 1 and args[0].endswith('...'):
1589 log_args = [args[0][:-1]] 1608 log_args = [args[0][:-1]]
1590 elif len(args) == 2: 1609 elif len(args) == 2:
1591 log_args = [args[0] + '..' + args[1]] 1610 log_args = [args[0] + '..' + args[1]]
1592 else: 1611 else:
1593 log_args = args[:] # Hope for the best! 1612 log_args = args[:] # Hope for the best!
1594 return RunGit(['log', '--pretty=format:%s\n\n%b'] + log_args) 1613 return RunGit(['log', '--pretty=format:%s\n\n%b'] + log_args)
1595 1614
1596 1615
1597 def CMDlint(parser, args): 1616 def CMDlint(parser, args):
1598 """Runs cpplint on the current changelist.""" 1617 """Runs cpplint on the current changelist."""
1599 parser.add_option('--filter', action='append', metavar='-x,+y', 1618 parser.add_option('--filter', action='append', metavar='-x,+y',
1600 help='Comma-separated list of cpplint\'s category-filters') 1619 help='Comma-separated list of cpplint\'s category-filters')
1601 (options, args) = parser.parse_args(args) 1620 auth.add_auth_options(parser)
1621 options, args = parser.parse_args(args)
1622 auth_config = auth.extract_auth_config_from_options(options)
1602 1623
1603 # Access to a protected member _XX of a client class 1624 # Access to a protected member _XX of a client class
1604 # pylint: disable=W0212 1625 # pylint: disable=W0212
1605 try: 1626 try:
1606 import cpplint 1627 import cpplint
1607 import cpplint_chromium 1628 import cpplint_chromium
1608 except ImportError: 1629 except ImportError:
1609 print "Your depot_tools is missing cpplint.py and/or cpplint_chromium.py." 1630 print "Your depot_tools is missing cpplint.py and/or cpplint_chromium.py."
1610 return 1 1631 return 1
1611 1632
1612 # Change the current working directory before calling lint so that it 1633 # Change the current working directory before calling lint so that it
1613 # shows the correct base. 1634 # shows the correct base.
1614 previous_cwd = os.getcwd() 1635 previous_cwd = os.getcwd()
1615 os.chdir(settings.GetRoot()) 1636 os.chdir(settings.GetRoot())
1616 try: 1637 try:
1617 cl = Changelist() 1638 cl = Changelist(auth_config=auth_config)
1618 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None) 1639 change = cl.GetChange(cl.GetCommonAncestorWithUpstream(), None)
1619 files = [f.LocalPath() for f in change.AffectedFiles()] 1640 files = [f.LocalPath() for f in change.AffectedFiles()]
1620 if not files: 1641 if not files:
1621 print "Cannot lint an empty CL" 1642 print "Cannot lint an empty CL"
1622 return 1 1643 return 1
1623 1644
1624 # Process cpplints arguments if any. 1645 # Process cpplints arguments if any.
1625 command = args + files 1646 command = args + files
1626 if options.filter: 1647 if options.filter:
1627 command = ['--filter=' + ','.join(options.filter)] + command 1648 command = ['--filter=' + ','.join(options.filter)] + command
(...skipping 18 matching lines...) Expand all
1646 return 1 1667 return 1
1647 return 0 1668 return 0
1648 1669
1649 1670
1650 def CMDpresubmit(parser, args): 1671 def CMDpresubmit(parser, args):
1651 """Runs presubmit tests on the current changelist.""" 1672 """Runs presubmit tests on the current changelist."""
1652 parser.add_option('-u', '--upload', action='store_true', 1673 parser.add_option('-u', '--upload', action='store_true',
1653 help='Run upload hook instead of the push/dcommit hook') 1674 help='Run upload hook instead of the push/dcommit hook')
1654 parser.add_option('-f', '--force', action='store_true', 1675 parser.add_option('-f', '--force', action='store_true',
1655 help='Run checks even if tree is dirty') 1676 help='Run checks even if tree is dirty')
1656 (options, args) = parser.parse_args(args) 1677 auth.add_auth_options(parser)
1678 options, args = parser.parse_args(args)
1679 auth_config = auth.extract_auth_config_from_options(options)
1657 1680
1658 if not options.force and is_dirty_git_tree('presubmit'): 1681 if not options.force and is_dirty_git_tree('presubmit'):
1659 print 'use --force to check even if tree is dirty.' 1682 print 'use --force to check even if tree is dirty.'
1660 return 1 1683 return 1
1661 1684
1662 cl = Changelist() 1685 cl = Changelist(auth_config=auth_config)
1663 if args: 1686 if args:
1664 base_branch = args[0] 1687 base_branch = args[0]
1665 else: 1688 else:
1666 # Default to diffing against the common ancestor of the upstream branch. 1689 # Default to diffing against the common ancestor of the upstream branch.
1667 base_branch = cl.GetCommonAncestorWithUpstream() 1690 base_branch = cl.GetCommonAncestorWithUpstream()
1668 1691
1669 cl.RunHook( 1692 cl.RunHook(
1670 committing=not options.upload, 1693 committing=not options.upload,
1671 may_prompt=False, 1694 may_prompt=False,
1672 verbose=options.verbose, 1695 verbose=options.verbose,
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1852 # If a pending prefix exists then replace refs/ with it. 1875 # If a pending prefix exists then replace refs/ with it.
1853 if pending_prefix: 1876 if pending_prefix:
1854 remote_branch = remote_branch.replace('refs/', pending_prefix) 1877 remote_branch = remote_branch.replace('refs/', pending_prefix)
1855 return remote_branch 1878 return remote_branch
1856 1879
1857 1880
1858 def RietveldUpload(options, args, cl, change): 1881 def RietveldUpload(options, args, cl, change):
1859 """upload the patch to rietveld.""" 1882 """upload the patch to rietveld."""
1860 upload_args = ['--assume_yes'] # Don't ask about untracked files. 1883 upload_args = ['--assume_yes'] # Don't ask about untracked files.
1861 upload_args.extend(['--server', cl.GetRietveldServer()]) 1884 upload_args.extend(['--server', cl.GetRietveldServer()])
1885 upload_args.extend(auth.auth_config_to_command_options(cl.auth_config))
1862 if options.emulate_svn_auto_props: 1886 if options.emulate_svn_auto_props:
1863 upload_args.append('--emulate_svn_auto_props') 1887 upload_args.append('--emulate_svn_auto_props')
1864 1888
1865 change_desc = None 1889 change_desc = None
1866 1890
1867 if options.email is not None: 1891 if options.email is not None:
1868 upload_args.extend(['--email', options.email]) 1892 upload_args.extend(['--email', options.email])
1869 1893
1870 if cl.GetIssue(): 1894 if cl.GetIssue():
1871 if options.title: 1895 if options.title:
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
2023 help='Squash multiple commits into one (Gerrit only)') 2047 help='Squash multiple commits into one (Gerrit only)')
2024 parser.add_option('--email', default=None, 2048 parser.add_option('--email', default=None,
2025 help='email address to use to connect to Rietveld') 2049 help='email address to use to connect to Rietveld')
2026 parser.add_option('--tbr-owners', dest='tbr_owners', action='store_true', 2050 parser.add_option('--tbr-owners', dest='tbr_owners', action='store_true',
2027 help='add a set of OWNERS to TBR') 2051 help='add a set of OWNERS to TBR')
2028 parser.add_option('--cq-dry-run', dest='cq_dry_run', action='store_true', 2052 parser.add_option('--cq-dry-run', dest='cq_dry_run', action='store_true',
2029 help='Send the patchset to do a CQ dry run right after ' 2053 help='Send the patchset to do a CQ dry run right after '
2030 'upload.') 2054 'upload.')
2031 2055
2032 add_git_similarity(parser) 2056 add_git_similarity(parser)
2057 auth.add_auth_options(parser)
2033 (options, args) = parser.parse_args(args) 2058 (options, args) = parser.parse_args(args)
2059 auth_config = auth.extract_auth_config_from_options(options)
2034 2060
2035 if is_dirty_git_tree('upload'): 2061 if is_dirty_git_tree('upload'):
2036 return 1 2062 return 1
2037 2063
2038 options.reviewers = cleanup_list(options.reviewers) 2064 options.reviewers = cleanup_list(options.reviewers)
2039 options.cc = cleanup_list(options.cc) 2065 options.cc = cleanup_list(options.cc)
2040 2066
2041 cl = Changelist() 2067 cl = Changelist(auth_config=auth_config)
2042 if args: 2068 if args:
2043 # TODO(ukai): is it ok for gerrit case? 2069 # TODO(ukai): is it ok for gerrit case?
2044 base_branch = args[0] 2070 base_branch = args[0]
2045 else: 2071 else:
2046 if cl.GetBranch() is None: 2072 if cl.GetBranch() is None:
2047 DieWithError('Can\'t upload from detached HEAD state. Get on a branch!') 2073 DieWithError('Can\'t upload from detached HEAD state. Get on a branch!')
2048 2074
2049 # Default to diffing against common ancestor of upstream branch 2075 # Default to diffing against common ancestor of upstream branch
2050 base_branch = cl.GetCommonAncestorWithUpstream() 2076 base_branch = cl.GetCommonAncestorWithUpstream()
2051 args = [base_branch, 'HEAD'] 2077 args = [base_branch, 'HEAD']
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 help='bypass upload presubmit hook') 2151 help='bypass upload presubmit hook')
2126 parser.add_option('-m', dest='message', 2152 parser.add_option('-m', dest='message',
2127 help="override review description") 2153 help="override review description")
2128 parser.add_option('-f', action='store_true', dest='force', 2154 parser.add_option('-f', action='store_true', dest='force',
2129 help="force yes to questions (don't prompt)") 2155 help="force yes to questions (don't prompt)")
2130 parser.add_option('-c', dest='contributor', 2156 parser.add_option('-c', dest='contributor',
2131 help="external contributor for patch (appended to " + 2157 help="external contributor for patch (appended to " +
2132 "description and used as author for git). Should be " + 2158 "description and used as author for git). Should be " +
2133 "formatted as 'First Last <email@example.com>'") 2159 "formatted as 'First Last <email@example.com>'")
2134 add_git_similarity(parser) 2160 add_git_similarity(parser)
2161 auth.add_auth_options(parser)
2135 (options, args) = parser.parse_args(args) 2162 (options, args) = parser.parse_args(args)
2136 cl = Changelist() 2163 auth_config = auth.extract_auth_config_from_options(options)
2164
2165 cl = Changelist(auth_config=auth_config)
2137 2166
2138 current = cl.GetBranch() 2167 current = cl.GetBranch()
2139 remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch()) 2168 remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
2140 if not settings.GetIsGitSvn() and remote == '.': 2169 if not settings.GetIsGitSvn() and remote == '.':
2141 print 2170 print
2142 print 'Attempting to push branch %r into another local branch!' % current 2171 print 'Attempting to push branch %r into another local branch!' % current
2143 print 2172 print
2144 print 'Either reparent this branch on top of origin/master:' 2173 print 'Either reparent this branch on top of origin/master:'
2145 print ' git reparent-branch --root' 2174 print ' git reparent-branch --root'
2146 print 2175 print
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2524 parser.add_option('-f', '--force', action='store_true', 2553 parser.add_option('-f', '--force', action='store_true',
2525 help='with -b, clobber any existing branch') 2554 help='with -b, clobber any existing branch')
2526 parser.add_option('-d', '--directory', action='store', metavar='DIR', 2555 parser.add_option('-d', '--directory', action='store', metavar='DIR',
2527 help='Change to the directory DIR immediately, ' 2556 help='Change to the directory DIR immediately, '
2528 'before doing anything else.') 2557 'before doing anything else.')
2529 parser.add_option('--reject', action='store_true', 2558 parser.add_option('--reject', action='store_true',
2530 help='failed patches spew .rej files rather than ' 2559 help='failed patches spew .rej files rather than '
2531 'attempting a 3-way merge') 2560 'attempting a 3-way merge')
2532 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit', 2561 parser.add_option('-n', '--no-commit', action='store_true', dest='nocommit',
2533 help="don't commit after patch applies") 2562 help="don't commit after patch applies")
2563 auth.add_auth_options(parser)
2534 (options, args) = parser.parse_args(args) 2564 (options, args) = parser.parse_args(args)
2565 auth_config = auth.extract_auth_config_from_options(options)
2566
2535 if len(args) != 1: 2567 if len(args) != 1:
2536 parser.print_help() 2568 parser.print_help()
2537 return 1 2569 return 1
2538 issue_arg = args[0] 2570 issue_arg = args[0]
2539 2571
2540 # We don't want uncommitted changes mixed up with the patch. 2572 # We don't want uncommitted changes mixed up with the patch.
2541 if is_dirty_git_tree('patch'): 2573 if is_dirty_git_tree('patch'):
2542 return 1 2574 return 1
2543 2575
2544 # TODO(maruel): Use apply_issue.py 2576 # TODO(maruel): Use apply_issue.py
2545 # TODO(ukai): use gerrit-cherry-pick for gerrit repository? 2577 # TODO(ukai): use gerrit-cherry-pick for gerrit repository?
2546 2578
2547 if options.newbranch: 2579 if options.newbranch:
2548 if options.force: 2580 if options.force:
2549 RunGit(['branch', '-D', options.newbranch], 2581 RunGit(['branch', '-D', options.newbranch],
2550 stderr=subprocess2.PIPE, error_ok=True) 2582 stderr=subprocess2.PIPE, error_ok=True)
2551 RunGit(['checkout', '-b', options.newbranch, 2583 RunGit(['checkout', '-b', options.newbranch,
2552 Changelist().GetUpstreamBranch()]) 2584 Changelist().GetUpstreamBranch()])
2553 2585
2554 return PatchIssue(issue_arg, options.reject, options.nocommit, 2586 return PatchIssue(issue_arg, options.reject, options.nocommit,
2555 options.directory) 2587 options.directory, auth_config)
2556 2588
2557 2589
2558 def PatchIssue(issue_arg, reject, nocommit, directory): 2590 def PatchIssue(issue_arg, reject, nocommit, directory, auth_config):
2559 # There's a "reset --hard" when failing to apply the patch. In order 2591 # There's a "reset --hard" when failing to apply the patch. In order
2560 # not to destroy users' data, make sure the tree is not dirty here. 2592 # not to destroy users' data, make sure the tree is not dirty here.
2561 assert(not is_dirty_git_tree('apply')) 2593 assert(not is_dirty_git_tree('apply'))
2562 2594
2563 if type(issue_arg) is int or issue_arg.isdigit(): 2595 if type(issue_arg) is int or issue_arg.isdigit():
2564 # Input is an issue id. Figure out the URL. 2596 # Input is an issue id. Figure out the URL.
2565 issue = int(issue_arg) 2597 issue = int(issue_arg)
2566 cl = Changelist(issue=issue) 2598 cl = Changelist(issue=issue, auth_config=auth_config)
2567 patchset = cl.GetMostRecentPatchset() 2599 patchset = cl.GetMostRecentPatchset()
2568 patch_data = cl.GetPatchSetDiff(issue, patchset) 2600 patch_data = cl.GetPatchSetDiff(issue, patchset)
2569 else: 2601 else:
2570 # Assume it's a URL to the patch. Default to https. 2602 # Assume it's a URL to the patch. Default to https.
2571 issue_url = gclient_utils.UpgradeToHttps(issue_arg) 2603 issue_url = gclient_utils.UpgradeToHttps(issue_arg)
2572 match = re.match(r'.*?/issue(\d+)_(\d+).diff', issue_url) 2604 match = re.match(r'.*?/issue(\d+)_(\d+).diff', issue_url)
2573 if not match: 2605 if not match:
2574 DieWithError('Must pass an issue ID or full URL for ' 2606 DieWithError('Must pass an issue ID or full URL for '
2575 '\'Download raw patch set\'') 2607 '\'Download raw patch set\'')
2576 issue = int(match.group(1)) 2608 issue = int(match.group(1))
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
2609 stdin=patch_data, stdout=subprocess2.VOID) 2641 stdin=patch_data, stdout=subprocess2.VOID)
2610 except subprocess2.CalledProcessError: 2642 except subprocess2.CalledProcessError:
2611 RunGit(['reset', '--hard']) 2643 RunGit(['reset', '--hard'])
2612 DieWithError('Failed to apply the patch') 2644 DieWithError('Failed to apply the patch')
2613 2645
2614 # If we had an issue, commit the current state and register the issue. 2646 # If we had an issue, commit the current state and register the issue.
2615 if not nocommit: 2647 if not nocommit:
2616 RunGit(['commit', '-m', ('patch from issue %(i)s at patchset ' 2648 RunGit(['commit', '-m', ('patch from issue %(i)s at patchset '
2617 '%(p)s (http://crrev.com/%(i)s#ps%(p)s)' 2649 '%(p)s (http://crrev.com/%(i)s#ps%(p)s)'
2618 % {'i': issue, 'p': patchset})]) 2650 % {'i': issue, 'p': patchset})])
2619 cl = Changelist() 2651 cl = Changelist(auth_config=auth_config)
2620 cl.SetIssue(issue) 2652 cl.SetIssue(issue)
2621 cl.SetPatchset(patchset) 2653 cl.SetPatchset(patchset)
2622 print "Committed patch locally." 2654 print "Committed patch locally."
2623 else: 2655 else:
2624 print "Patch applied to index." 2656 print "Patch applied to index."
2625 return 0 2657 return 0
2626 2658
2627 2659
2628 def CMDrebase(parser, args): 2660 def CMDrebase(parser, args):
2629 """Rebases current branch on top of svn repo.""" 2661 """Rebases current branch on top of svn repo."""
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2729 "-c", "--clobber", action="store_true", default=False, 2761 "-c", "--clobber", action="store_true", default=False,
2730 help="Force a clobber before building; e.g. don't do an " 2762 help="Force a clobber before building; e.g. don't do an "
2731 "incremental build") 2763 "incremental build")
2732 group.add_option( 2764 group.add_option(
2733 "--project", 2765 "--project",
2734 help="Override which project to use. Projects are defined " 2766 help="Override which project to use. Projects are defined "
2735 "server-side to define what default bot set to use") 2767 "server-side to define what default bot set to use")
2736 group.add_option( 2768 group.add_option(
2737 "-n", "--name", help="Try job name; default to current branch name") 2769 "-n", "--name", help="Try job name; default to current branch name")
2738 parser.add_option_group(group) 2770 parser.add_option_group(group)
2771 auth.add_auth_options(parser)
2739 options, args = parser.parse_args(args) 2772 options, args = parser.parse_args(args)
2773 auth_config = auth.extract_auth_config_from_options(options)
2740 2774
2741 if args: 2775 if args:
2742 parser.error('Unknown arguments: %s' % args) 2776 parser.error('Unknown arguments: %s' % args)
2743 2777
2744 cl = Changelist() 2778 cl = Changelist(auth_config=auth_config)
2745 if not cl.GetIssue(): 2779 if not cl.GetIssue():
2746 parser.error('Need to upload first') 2780 parser.error('Need to upload first')
2747 2781
2748 props = cl.GetIssueProperties() 2782 props = cl.GetIssueProperties()
2749 if props.get('closed'): 2783 if props.get('closed'):
2750 parser.error('Cannot send tryjobs for a closed CL') 2784 parser.error('Cannot send tryjobs for a closed CL')
2751 2785
2752 if props.get('private'): 2786 if props.get('private'):
2753 parser.error('Cannot use trybots with private issue') 2787 parser.error('Cannot use trybots with private issue')
2754 2788
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
2882 if not issue_url: 2916 if not issue_url:
2883 print >> sys.stderr, 'ERROR No issue to open' 2917 print >> sys.stderr, 'ERROR No issue to open'
2884 return 1 2918 return 1
2885 2919
2886 webbrowser.open(issue_url) 2920 webbrowser.open(issue_url)
2887 return 0 2921 return 0
2888 2922
2889 2923
2890 def CMDset_commit(parser, args): 2924 def CMDset_commit(parser, args):
2891 """Sets the commit bit to trigger the Commit Queue.""" 2925 """Sets the commit bit to trigger the Commit Queue."""
2892 _, args = parser.parse_args(args) 2926 auth.add_auth_options(parser)
2927 options, args = parser.parse_args(args)
2928 auth_config = auth.extract_auth_config_from_options(options)
2893 if args: 2929 if args:
2894 parser.error('Unrecognized args: %s' % ' '.join(args)) 2930 parser.error('Unrecognized args: %s' % ' '.join(args))
2895 cl = Changelist() 2931 cl = Changelist(auth_config=auth_config)
2896 props = cl.GetIssueProperties() 2932 props = cl.GetIssueProperties()
2897 if props.get('private'): 2933 if props.get('private'):
2898 parser.error('Cannot set commit on private issue') 2934 parser.error('Cannot set commit on private issue')
2899 cl.SetFlag('commit', '1') 2935 cl.SetFlag('commit', '1')
2900 return 0 2936 return 0
2901 2937
2902 2938
2903 def CMDset_close(parser, args): 2939 def CMDset_close(parser, args):
2904 """Closes the issue.""" 2940 """Closes the issue."""
2905 _, args = parser.parse_args(args) 2941 auth.add_auth_options(parser)
2942 options, args = parser.parse_args(args)
2943 auth_config = auth.extract_auth_config_from_options(options)
2906 if args: 2944 if args:
2907 parser.error('Unrecognized args: %s' % ' '.join(args)) 2945 parser.error('Unrecognized args: %s' % ' '.join(args))
2908 cl = Changelist() 2946 cl = Changelist(auth_config=auth_config)
2909 # Ensure there actually is an issue to close. 2947 # Ensure there actually is an issue to close.
2910 cl.GetDescription() 2948 cl.GetDescription()
2911 cl.CloseIssue() 2949 cl.CloseIssue()
2912 return 0 2950 return 0
2913 2951
2914 2952
2915 def CMDdiff(parser, args): 2953 def CMDdiff(parser, args):
2916 """Shows differences between local tree and last upload.""" 2954 """Shows differences between local tree and last upload."""
2917 parser.parse_args(args) 2955 auth.add_auth_options(parser)
2956 options, args = parser.parse_args(args)
2957 auth_config = auth.extract_auth_config_from_options(options)
2958 if args:
2959 parser.error('Unrecognized args: %s' % ' '.join(args))
2918 2960
2919 # Uncommitted (staged and unstaged) changes will be destroyed by 2961 # Uncommitted (staged and unstaged) changes will be destroyed by
2920 # "git reset --hard" if there are merging conflicts in PatchIssue(). 2962 # "git reset --hard" if there are merging conflicts in PatchIssue().
2921 # Staged changes would be committed along with the patch from last 2963 # Staged changes would be committed along with the patch from last
2922 # upload, hence counted toward the "last upload" side in the final 2964 # upload, hence counted toward the "last upload" side in the final
2923 # diff output, and this is not what we want. 2965 # diff output, and this is not what we want.
2924 if is_dirty_git_tree('diff'): 2966 if is_dirty_git_tree('diff'):
2925 return 1 2967 return 1
2926 2968
2927 cl = Changelist() 2969 cl = Changelist(auth_config=auth_config)
2928 issue = cl.GetIssue() 2970 issue = cl.GetIssue()
2929 branch = cl.GetBranch() 2971 branch = cl.GetBranch()
2930 if not issue: 2972 if not issue:
2931 DieWithError('No issue found for current branch (%s)' % branch) 2973 DieWithError('No issue found for current branch (%s)' % branch)
2932 TMP_BRANCH = 'git-cl-diff' 2974 TMP_BRANCH = 'git-cl-diff'
2933 base_branch = cl.GetCommonAncestorWithUpstream() 2975 base_branch = cl.GetCommonAncestorWithUpstream()
2934 2976
2935 # Create a new branch based on the merge-base 2977 # Create a new branch based on the merge-base
2936 RunGit(['checkout', '-q', '-b', TMP_BRANCH, base_branch]) 2978 RunGit(['checkout', '-q', '-b', TMP_BRANCH, base_branch])
2937 try: 2979 try:
2938 # Patch in the latest changes from rietveld. 2980 # Patch in the latest changes from rietveld.
2939 rtn = PatchIssue(issue, False, False, None) 2981 rtn = PatchIssue(issue, False, False, None, auth_config)
2940 if rtn != 0: 2982 if rtn != 0:
2941 return rtn 2983 return rtn
2942 2984
2943 # Switch back to starting branch and diff against the temporary 2985 # Switch back to starting branch and diff against the temporary
2944 # branch containing the latest rietveld patch. 2986 # branch containing the latest rietveld patch.
2945 subprocess2.check_call(['git', 'diff', TMP_BRANCH, branch, '--']) 2987 subprocess2.check_call(['git', 'diff', TMP_BRANCH, branch, '--'])
2946 finally: 2988 finally:
2947 RunGit(['checkout', '-q', branch]) 2989 RunGit(['checkout', '-q', branch])
2948 RunGit(['branch', '-D', TMP_BRANCH]) 2990 RunGit(['branch', '-D', TMP_BRANCH])
2949 2991
2950 return 0 2992 return 0
2951 2993
2952 2994
2953 def CMDowners(parser, args): 2995 def CMDowners(parser, args):
2954 """Interactively find the owners for reviewing.""" 2996 """Interactively find the owners for reviewing."""
2955 parser.add_option( 2997 parser.add_option(
2956 '--no-color', 2998 '--no-color',
2957 action='store_true', 2999 action='store_true',
2958 help='Use this option to disable color output') 3000 help='Use this option to disable color output')
3001 auth.add_auth_options(parser)
2959 options, args = parser.parse_args(args) 3002 options, args = parser.parse_args(args)
3003 auth_config = auth.extract_auth_config_from_options(options)
2960 3004
2961 author = RunGit(['config', 'user.email']).strip() or None 3005 author = RunGit(['config', 'user.email']).strip() or None
2962 3006
2963 cl = Changelist() 3007 cl = Changelist(auth_config=auth_config)
2964 3008
2965 if args: 3009 if args:
2966 if len(args) > 1: 3010 if len(args) > 1:
2967 parser.error('Unknown args') 3011 parser.error('Unknown args')
2968 base_branch = args[0] 3012 base_branch = args[0]
2969 else: 3013 else:
2970 # Default to diffing against the common ancestor of the upstream branch. 3014 # Default to diffing against the common ancestor of the upstream branch.
2971 base_branch = cl.GetCommonAncestorWithUpstream() 3015 base_branch = cl.GetCommonAncestorWithUpstream()
2972 3016
2973 change = cl.GetChange(base_branch, None) 3017 change = cl.GetChange(base_branch, None)
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
3161 if __name__ == '__main__': 3205 if __name__ == '__main__':
3162 # These affect sys.stdout so do it outside of main() to simplify mocks in 3206 # These affect sys.stdout so do it outside of main() to simplify mocks in
3163 # unit testing. 3207 # unit testing.
3164 fix_encoding.fix_encoding() 3208 fix_encoding.fix_encoding()
3165 colorama.init() 3209 colorama.init()
3166 try: 3210 try:
3167 sys.exit(main(sys.argv[1:])) 3211 sys.exit(main(sys.argv[1:]))
3168 except KeyboardInterrupt: 3212 except KeyboardInterrupt:
3169 sys.stderr.write('interrupted\n') 3213 sys.stderr.write('interrupted\n')
3170 sys.exit(1) 3214 sys.exit(1)
OLDNEW
« no previous file with comments | « git_cherry_pick_upload.py ('k') | my_activity.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698