OLD | NEW |
---|---|
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 1487 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1498 else len(branches_to_fetch)) | 1498 else len(branches_to_fetch)) |
1499 for x in pool.imap_unordered(fetch, branches_to_fetch): | 1499 for x in pool.imap_unordered(fetch, branches_to_fetch): |
1500 yield x | 1500 yield x |
1501 else: | 1501 else: |
1502 # Do not use GetApprovingReviewers(), since it requires an HTTP request. | 1502 # Do not use GetApprovingReviewers(), since it requires an HTTP request. |
1503 for b in branches: | 1503 for b in branches: |
1504 c = Changelist(branchref=b, auth_config=auth_config) | 1504 c = Changelist(branchref=b, auth_config=auth_config) |
1505 url = c.GetIssueURL() | 1505 url = c.GetIssueURL() |
1506 yield (b, url, Fore.BLUE if url else Fore.WHITE) | 1506 yield (b, url, Fore.BLUE if url else Fore.WHITE) |
1507 | 1507 |
1508 | |
1509 def CMDupload_branch_deps(unused_parser, args): | |
1510 """Uploads CLs of local branches that are dependents of the current branch. | |
1511 | |
1512 If the local branch dependency tree looks like: | |
1513 test1 -> test2.1 -> test3.1 | |
1514 -> test3.2 | |
1515 -> test2.2 -> test3.3 | |
1516 | |
1517 and you run this command from test1 then "git cl upload" is run on the | |
1518 dependent branches in this order: | |
1519 test2.1, test3.1, test3.2, test2.2, test3.3 | |
1520 | |
1521 Note: This command does not rebase your local dependent branches. Use it when | |
1522 you make a change to the parent branch that will not conflict with its | |
1523 dependent branches, and you would like their dependencies updated in | |
1524 Rietveld. | |
nodir
2015/06/15 23:50:22
Rebasing would be very nice, for example if I want
iannucci
2015/06/15 23:55:12
git rebase-update can/does already do this.
nodir
2015/06/15 23:58:43
Acknowledged.
| |
1525 """ | |
1526 | |
1527 branchref = RunGit(['symbolic-ref', 'HEAD'], | |
1528 stderr=subprocess2.VOID, error_ok=True).strip() | |
1529 parent_branch = ShortBranchName(branchref) | |
nodir
2015/06/15 23:50:21
nit: call it root_branch?
rmistry
2015/06/17 17:58:46
Done.
| |
1530 if parent_branch is None: | |
1531 DieWithError('Can\'t find dependent branches from detached HEAD state. ' | |
1532 'Get on a branch!') | |
1533 | |
1534 branches = RunGit(['for-each-ref', | |
1535 '--format=%(refname:short) %(upstream:short)', | |
1536 'refs/heads']) | |
1537 if not branches: | |
1538 print('No local branches found.') | |
1539 return 0 | |
1540 | |
1541 # Create a dictionary of all local branches to the branches that are dependent | |
1542 # on it. | |
1543 tracked_to_dependents = {} | |
nodir
2015/06/15 23:50:21
collections.defaultdict([])
lines 1546-1547 can be
rmistry
2015/06/17 17:58:45
Cool. Done.
| |
1544 for b in branches.splitlines(): | |
1545 branch_name, tracked = b.split() | |
nodir
2015/06/15 23:50:22
this will crash on a non-tracked branch: b.split()
rmistry
2015/06/17 17:58:45
Done.
| |
1546 if tracked not in tracked_to_dependents: | |
1547 tracked_to_dependents[tracked] = [] | |
1548 tracked_to_dependents[tracked].append(branch_name) | |
iannucci
2015/06/15 23:55:12
It would be worth consolidating this branch hierar
rmistry
2015/06/17 17:58:45
I looked at git_rebase_update and tried using some
| |
1549 | |
1550 print | |
1551 print 'The dependent local branches of %s are:' % parent_branch | |
1552 inorder_dependents = [] | |
nodir
2015/06/15 23:50:22
nit: "inorder" is somewhat confusing because it is
rmistry
2015/06/17 17:58:46
Oops. Yea I meant preorder here.
| |
1553 def traverse_dependents_inorder(branch, padding=''): | |
1554 dependents_to_process = tracked_to_dependents.get(branch, []) | |
1555 padding += ' ' | |
1556 for dependent in dependents_to_process: | |
1557 print '%s%s' % (padding, dependent) | |
1558 inorder_dependents.append(dependent) | |
1559 traverse_dependents_inorder(dependent, padding) | |
1560 traverse_dependents_inorder(parent_branch) | |
1561 print | |
1562 | |
1563 print ('This command will checkout all dependent branches and run ' | |
1564 '"git cl upload".') | |
1565 ask_for_data('[Press enter to dcommit or ctrl-C to quit]') | |
1566 | |
1567 # Go through all dependents, checkout the branch and upload. | |
1568 if inorder_dependents: | |
nodir
2015/06/15 23:50:22
inverse the condition, return early and deindent t
rmistry
2015/06/17 17:58:45
Done.
| |
1569 try: | |
1570 for dependent_branch in inorder_dependents: | |
1571 print | |
1572 print '--------------------------------------' | |
1573 print 'Running "git cl upload" from %s:' % dependent_branch | |
1574 RunGit(['checkout', '-q', dependent_branch]) | |
nodir
2015/06/15 23:50:22
can CMDupload_branch_deps be called when the work
rmistry
2015/06/17 17:58:45
At this point you have checked out a branch so AFA
| |
1575 print | |
1576 if CMDupload(OptionParser(), args) != 0: | |
nodir
2015/06/15 23:50:22
Will it ask for pathset title every time?
I think
rmistry
2015/06/17 17:58:45
I wanted to do this when I started this CL but for
| |
1577 print 'Upload failed for %s!' % dependent_branch | |
nodir
2015/06/15 23:50:21
I think users would thank you if you check that th
rmistry
2015/06/17 17:58:45
Yea I think that is an optimization that can be ma
| |
1578 return -1 | |
1579 print | |
1580 finally: | |
1581 # Swap back to the original parent branch. | |
1582 RunGit(['checkout', '-q', parent_branch]) | |
1583 | |
1584 print | |
1585 print 'All dependent branches %s have been updated!' % inorder_dependents | |
1586 print | |
1587 else: | |
1588 print 'There are no dependent local branches for %s' % parent_branch | |
1589 | |
1590 return 0 | |
1591 | |
1592 | |
1508 def CMDstatus(parser, args): | 1593 def CMDstatus(parser, args): |
1509 """Show status of changelists. | 1594 """Show status of changelists. |
1510 | 1595 |
1511 Colors are used to tell the state of the CL unless --fast is used: | 1596 Colors are used to tell the state of the CL unless --fast is used: |
1512 - Red not sent for review or broken | 1597 - Red not sent for review or broken |
1513 - Blue waiting for review | 1598 - Blue waiting for review |
1514 - Yellow waiting for you to reply to review | 1599 - Yellow waiting for you to reply to review |
1515 - Green LGTM'ed | 1600 - Green LGTM'ed |
1516 - Magenta in the commit queue | 1601 - Magenta in the commit queue |
1517 - Cyan was committed, branch can be deleted | 1602 - Cyan was committed, branch can be deleted |
(...skipping 1847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3365 if __name__ == '__main__': | 3450 if __name__ == '__main__': |
3366 # These affect sys.stdout so do it outside of main() to simplify mocks in | 3451 # These affect sys.stdout so do it outside of main() to simplify mocks in |
3367 # unit testing. | 3452 # unit testing. |
3368 fix_encoding.fix_encoding() | 3453 fix_encoding.fix_encoding() |
3369 colorama.init() | 3454 colorama.init() |
3370 try: | 3455 try: |
3371 sys.exit(main(sys.argv[1:])) | 3456 sys.exit(main(sys.argv[1:])) |
3372 except KeyboardInterrupt: | 3457 except KeyboardInterrupt: |
3373 sys.stderr.write('interrupted\n') | 3458 sys.stderr.write('interrupted\n') |
3374 sys.exit(1) | 3459 sys.exit(1) |
OLD | NEW |