Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 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 import logging | 10 import logging |
| (...skipping 29 matching lines...) Expand all Loading... | |
| 40 import rietveld | 40 import rietveld |
| 41 import scm | 41 import scm |
| 42 import subprocess2 | 42 import subprocess2 |
| 43 import watchlists | 43 import watchlists |
| 44 | 44 |
| 45 | 45 |
| 46 DEFAULT_SERVER = 'http://codereview.appspot.com' | 46 DEFAULT_SERVER = 'http://codereview.appspot.com' |
| 47 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' | 47 POSTUPSTREAM_HOOK_PATTERN = '.git/hooks/post-cl-%s' |
| 48 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' | 48 DESCRIPTION_BACKUP_FILE = '~/.git_cl_description_backup' |
| 49 | 49 |
| 50 GERRIT_FETCH_URL = 'http://git.chromium.org' | |
|
M-A Ruel
2011/12/07 19:21:28
No, don't hard code them. If you look again, there
| |
| 51 # Note these are assuming users have set up ~/.ssh/config stanzas | |
| 52 # as recommended so that no port numbers are required. | |
| 53 GERRIT_PUSH_URL = 'ssh://gerrit.chromium.org' | |
| 54 GERRIT_COMMIT_HOOK = 'gerrit.chromium.org:hooks/commit-msg' | |
| 55 | |
| 50 | 56 |
| 51 # Initialized in main() | 57 # Initialized in main() |
| 52 settings = None | 58 settings = None |
| 53 | 59 |
| 54 | 60 |
| 55 def DieWithError(message): | 61 def DieWithError(message): |
| 56 print >> sys.stderr, message | 62 print >> sys.stderr, message |
| 57 sys.exit(1) | 63 sys.exit(1) |
| 58 | 64 |
| 59 | 65 |
| (...skipping 664 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 724 SetProperty('viewvc-url', 'VIEW_VC', unset_error_ok=True) | 730 SetProperty('viewvc-url', 'VIEW_VC', unset_error_ok=True) |
| 725 | 731 |
| 726 if 'PUSH_URL_CONFIG' in keyvals and 'ORIGIN_URL_CONFIG' in keyvals: | 732 if 'PUSH_URL_CONFIG' in keyvals and 'ORIGIN_URL_CONFIG' in keyvals: |
| 727 #should be of the form | 733 #should be of the form |
| 728 #PUSH_URL_CONFIG: url.ssh://gitrw.chromium.org.pushinsteadof | 734 #PUSH_URL_CONFIG: url.ssh://gitrw.chromium.org.pushinsteadof |
| 729 #ORIGIN_URL_CONFIG: http://src.chromium.org/git | 735 #ORIGIN_URL_CONFIG: http://src.chromium.org/git |
| 730 RunGit(['config', keyvals['PUSH_URL_CONFIG'], | 736 RunGit(['config', keyvals['PUSH_URL_CONFIG'], |
| 731 keyvals['ORIGIN_URL_CONFIG']]) | 737 keyvals['ORIGIN_URL_CONFIG']]) |
| 732 | 738 |
| 733 | 739 |
| 740 def GerritConfig(options, args): | |
| 741 """Set up git config for use with Gerrit.""" | |
| 742 | |
| 743 # Install the standard commit-msg hook. | |
| 744 RunCommand(['scp', '-p', GERRIT_COMMIT_HOOK, | |
| 745 os.path.join('.git', 'hooks', 'commit-msg')]) | |
| 746 | |
| 747 # Set the standard URL mapping. | |
| 748 RunGit(['config', | |
| 749 'url.' + GERRIT_PUSH_URL + '.pushinsteadof', GERRIT_FETCH_URL]) | |
| 750 | |
| 751 | |
| 734 @usage('[repo root containing codereview.settings]') | 752 @usage('[repo root containing codereview.settings]') |
| 735 def CMDconfig(parser, args): | 753 def CMDconfig(parser, args): |
| 736 """edit configuration for this tree""" | 754 """edit configuration for this tree""" |
| 755 parser.add_option('-g', '--gerrit', action='store_true', | |
|
M-A Ruel
2011/12/07 19:21:28
It should be automatic, no need for flags.
| |
| 756 help='Configure for Gerrit rather than Rietveld') | |
| 757 options, args = parser.parse_args(args) | |
| 737 | 758 |
| 738 _, args = parser.parse_args(args) | 759 if options.gerrit: |
| 760 return GerritConfig(options, args) | |
| 761 | |
| 739 if len(args) == 0: | 762 if len(args) == 0: |
| 740 GetCodereviewSettingsInteractively() | 763 GetCodereviewSettingsInteractively() |
| 741 return 0 | 764 return 0 |
| 742 | 765 |
| 743 url = args[0] | 766 url = args[0] |
| 744 if not url.endswith('codereview.settings'): | 767 if not url.endswith('codereview.settings'): |
| 745 url = os.path.join(url, 'codereview.settings') | 768 url = os.path.join(url, 'codereview.settings') |
| 746 | 769 |
| 747 # Load code review settings and download hooks (if available). | 770 # Load code review settings and download hooks (if available). |
| 748 LoadCodereviewSettingsFromFile(urllib2.urlopen(url)) | 771 LoadCodereviewSettingsFromFile(urllib2.urlopen(url)) |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 856 else: | 879 else: |
| 857 # Default to diffing against the "upstream" branch. | 880 # Default to diffing against the "upstream" branch. |
| 858 base_branch = cl.GetUpstreamBranch() | 881 base_branch = cl.GetUpstreamBranch() |
| 859 | 882 |
| 860 cl.RunHook(committing=not options.upload, upstream_branch=base_branch, | 883 cl.RunHook(committing=not options.upload, upstream_branch=base_branch, |
| 861 may_prompt=False, verbose=options.verbose, | 884 may_prompt=False, verbose=options.verbose, |
| 862 author=None) | 885 author=None) |
| 863 return 0 | 886 return 0 |
| 864 | 887 |
| 865 | 888 |
| 889 def GerritUpload(options, args): | |
| 890 # We assume the remote called "origin" is the one we want. | |
| 891 # It's probably not worthwhile to support different workflows. | |
|
M-A Ruel
2011/12/07 19:21:28
It is.
| |
| 892 remote = 'origin' | |
| 893 | |
| 894 branch = 'master' | |
| 895 if options.for_branch is not None: | |
| 896 branch = options.for_branch | |
| 897 | |
| 898 receive_options = [] | |
| 899 | |
| 900 if options.cc is not None: | |
| 901 receive_options += ['--cc=' + email for email in | |
| 902 options.cc.split(',')] | |
| 903 if options.reviewers is not None: | |
| 904 receive_options += ['--reviewer=' + email for email in | |
| 905 options.reviewers.split(',')] | |
| 906 | |
| 907 git_command = ['push'] | |
| 908 if receive_options: | |
| 909 git_command.append('--receive-pack=git receive-pack ' + | |
| 910 ' '.join(receive_options)) | |
| 911 git_command += [remote, 'HEAD:refs/for/' + branch] | |
| 912 | |
| 913 RunGit(git_command) | |
| 914 return 0 | |
| 915 | |
| 916 | |
| 866 @usage('[args to "git diff"]') | 917 @usage('[args to "git diff"]') |
| 867 def CMDupload(parser, args): | 918 def CMDupload(parser, args): |
| 868 """upload the current changelist to codereview""" | 919 """upload the current changelist to codereview""" |
| 869 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', | 920 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', |
| 870 help='bypass upload presubmit hook') | 921 help='bypass upload presubmit hook') |
| 871 parser.add_option('-f', action='store_true', dest='force', | 922 parser.add_option('-f', action='store_true', dest='force', |
| 872 help="force yes to questions (don't prompt)") | 923 help="force yes to questions (don't prompt)") |
| 873 parser.add_option('-m', dest='message', help='message for patch') | 924 parser.add_option('-m', dest='message', help='message for patch') |
| 874 parser.add_option('-r', '--reviewers', | 925 parser.add_option('-r', '--reviewers', |
| 875 help='reviewer email addresses') | 926 help='reviewer email addresses') |
| 876 parser.add_option('--cc', | 927 parser.add_option('--cc', |
| 877 help='cc email addresses') | 928 help='cc email addresses') |
| 878 parser.add_option('--send-mail', action='store_true', | 929 parser.add_option('--send-mail', action='store_true', |
| 879 help='send email to reviewer immediately') | 930 help='send email to reviewer immediately') |
| 880 parser.add_option("--emulate_svn_auto_props", action="store_true", | 931 parser.add_option("--emulate_svn_auto_props", action="store_true", |
| 881 dest="emulate_svn_auto_props", | 932 dest="emulate_svn_auto_props", |
| 882 help="Emulate Subversion's auto properties feature.") | 933 help="Emulate Subversion's auto properties feature.") |
| 883 parser.add_option("--desc_from_logs", action="store_true", | 934 parser.add_option("--desc_from_logs", action="store_true", |
| 884 dest="from_logs", | 935 dest="from_logs", |
| 885 help="""Squashes git commit logs into change description and | 936 help="""Squashes git commit logs into change description and |
| 886 uses message as subject""") | 937 uses message as subject""") |
| 887 parser.add_option('-c', '--use-commit-queue', action='store_true', | 938 parser.add_option('-c', '--use-commit-queue', action='store_true', |
| 888 help='tell the commit queue to commit this patchset') | 939 help='tell the commit queue to commit this patchset') |
| 940 parser.add_option('-g', '--gerrit', action='store_true', | |
| 941 help='Send change to Gerrit rather than Rietveld') | |
| 942 parser.add_option('-b', '--for-branch', | |
| 943 help='Gerrit branch to send change to') | |
| 889 (options, args) = parser.parse_args(args) | 944 (options, args) = parser.parse_args(args) |
| 890 | 945 |
| 946 # TODO(mcgrathr): Perhaps look at some git-config variable stored | |
| 947 # by GerritConfig to default to gerrit mode? | |
| 948 if options.gerrit and (options.bypass_hooks or | |
| 949 options.message or | |
| 950 options.from_logs or | |
| 951 options.use_commit_queue): | |
| 952 print 'The --gerrit (-g) option is incompatible with most other options.' | |
| 953 return 1 | |
| 954 | |
| 891 # Make sure index is up-to-date before running diff-index. | 955 # Make sure index is up-to-date before running diff-index. |
| 892 RunGit(['update-index', '--refresh', '-q'], error_ok=True) | 956 RunGit(['update-index', '--refresh', '-q'], error_ok=True) |
| 893 if RunGit(['diff-index', 'HEAD']): | 957 if RunGit(['diff-index', 'HEAD']): |
| 894 print 'Cannot upload with a dirty tree. You must commit locally first.' | 958 print 'Cannot upload with a dirty tree. You must commit locally first.' |
| 895 return 1 | 959 return 1 |
| 896 | 960 |
| 961 if options.gerrit: | |
| 962 return GerritUpload(options, args) | |
| 963 | |
| 897 cl = Changelist() | 964 cl = Changelist() |
| 898 if args: | 965 if args: |
| 899 base_branch = args[0] | 966 base_branch = args[0] |
| 900 else: | 967 else: |
| 901 # Default to diffing against the "upstream" branch. | 968 # Default to diffing against the "upstream" branch. |
| 902 base_branch = cl.GetUpstreamBranch() | 969 base_branch = cl.GetUpstreamBranch() |
| 903 args = [base_branch + "..."] | 970 args = [base_branch + "..."] |
| 904 | 971 |
| 905 if not options.bypass_hooks and not options.force: | 972 if not options.bypass_hooks and not options.force: |
| 906 hook_results = cl.RunHook(committing=False, upstream_branch=base_branch, | 973 hook_results = cl.RunHook(committing=False, upstream_branch=base_branch, |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1416 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1483 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 1417 | 1484 |
| 1418 # Not a known command. Default to help. | 1485 # Not a known command. Default to help. |
| 1419 GenUsage(parser, 'help') | 1486 GenUsage(parser, 'help') |
| 1420 return CMDhelp(parser, argv) | 1487 return CMDhelp(parser, argv) |
| 1421 | 1488 |
| 1422 | 1489 |
| 1423 if __name__ == '__main__': | 1490 if __name__ == '__main__': |
| 1424 fix_encoding.fix_encoding() | 1491 fix_encoding.fix_encoding() |
| 1425 sys.exit(main(sys.argv[1:])) | 1492 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |