| 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 errno | 10 import errno |
| (...skipping 492 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 503 """Set this branch's issue. If issue=0, clears the issue.""" | 503 """Set this branch's issue. If issue=0, clears the issue.""" |
| 504 if issue: | 504 if issue: |
| 505 RunGit(['config', self._IssueSetting(), str(issue)]) | 505 RunGit(['config', self._IssueSetting(), str(issue)]) |
| 506 if self.rietveld_server: | 506 if self.rietveld_server: |
| 507 RunGit(['config', self._RietveldServer(), self.rietveld_server]) | 507 RunGit(['config', self._RietveldServer(), self.rietveld_server]) |
| 508 else: | 508 else: |
| 509 RunGit(['config', '--unset', self._IssueSetting()]) | 509 RunGit(['config', '--unset', self._IssueSetting()]) |
| 510 self.SetPatchset(0) | 510 self.SetPatchset(0) |
| 511 self.has_issue = False | 511 self.has_issue = False |
| 512 | 512 |
| 513 def RunHook(self, committing, upstream_branch, tbr, may_prompt, verbose, | 513 def RunHook(self, committing, upstream_branch, may_prompt, verbose, author): |
| 514 author): | |
| 515 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" | 514 """Calls sys.exit() if the hook fails; returns a HookResults otherwise.""" |
| 516 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() or '.' | 515 root = RunCommand(['git', 'rev-parse', '--show-cdup']).strip() or '.' |
| 517 absroot = os.path.abspath(root) | 516 absroot = os.path.abspath(root) |
| 518 | 517 |
| 519 # We use the sha1 of HEAD as a name of this change. | 518 # We use the sha1 of HEAD as a name of this change. |
| 520 name = RunCommand(['git', 'rev-parse', 'HEAD']).strip() | 519 name = RunCommand(['git', 'rev-parse', 'HEAD']).strip() |
| 521 # Need to pass a relative path for msysgit. | 520 # Need to pass a relative path for msysgit. |
| 522 files = scm.GIT.CaptureStatus([root], upstream_branch) | 521 files = scm.GIT.CaptureStatus([root], upstream_branch) |
| 523 | 522 |
| 524 issue = ConvertToInteger(self.GetIssue()) | 523 issue = ConvertToInteger(self.GetIssue()) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 545 | 544 |
| 546 # Apply watchlists on upload. | 545 # Apply watchlists on upload. |
| 547 if not committing: | 546 if not committing: |
| 548 watchlist = watchlists.Watchlists(change.RepositoryRoot()) | 547 watchlist = watchlists.Watchlists(change.RepositoryRoot()) |
| 549 files = [f.LocalPath() for f in change.AffectedFiles()] | 548 files = [f.LocalPath() for f in change.AffectedFiles()] |
| 550 self.SetWatchers(watchlist.GetWatchersForPaths(files)) | 549 self.SetWatchers(watchlist.GetWatchersForPaths(files)) |
| 551 | 550 |
| 552 try: | 551 try: |
| 553 output = presubmit_support.DoPresubmitChecks(change, committing, | 552 output = presubmit_support.DoPresubmitChecks(change, committing, |
| 554 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, | 553 verbose=verbose, output_stream=sys.stdout, input_stream=sys.stdin, |
| 555 default_presubmit=None, may_prompt=may_prompt, tbr=tbr, | 554 default_presubmit=None, may_prompt=may_prompt, |
| 556 rietveld_obj=self.RpcServer()) | 555 rietveld_obj=self.RpcServer()) |
| 557 except presubmit_support.PresubmitFailure, e: | 556 except presubmit_support.PresubmitFailure, e: |
| 558 DieWithError( | 557 DieWithError( |
| 559 ('%s\nMaybe your depot_tools is out of date?\n' | 558 ('%s\nMaybe your depot_tools is out of date?\n' |
| 560 'If all fails, contact maruel@') % e) | 559 'If all fails, contact maruel@') % e) |
| 561 | 560 |
| 562 # TODO(dpranke): We should propagate the error out instead of calling | 561 # TODO(dpranke): We should propagate the error out instead of calling |
| 563 # exit(). | 562 # exit(). |
| 564 if not output.should_continue(): | 563 if not output.should_continue(): |
| 565 sys.exit(1) | 564 sys.exit(1) |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 890 return 1 | 889 return 1 |
| 891 | 890 |
| 892 cl = Changelist() | 891 cl = Changelist() |
| 893 if args: | 892 if args: |
| 894 base_branch = args[0] | 893 base_branch = args[0] |
| 895 else: | 894 else: |
| 896 # Default to diffing against the "upstream" branch. | 895 # Default to diffing against the "upstream" branch. |
| 897 base_branch = cl.GetUpstreamBranch() | 896 base_branch = cl.GetUpstreamBranch() |
| 898 | 897 |
| 899 cl.RunHook(committing=not options.upload, upstream_branch=base_branch, | 898 cl.RunHook(committing=not options.upload, upstream_branch=base_branch, |
| 900 tbr=False, may_prompt=False, verbose=options.verbose, | 899 may_prompt=False, verbose=options.verbose, |
| 901 author=None) | 900 author=None) |
| 902 return 0 | 901 return 0 |
| 903 | 902 |
| 904 | 903 |
| 905 @usage('[args to "git diff"]') | 904 @usage('[args to "git diff"]') |
| 906 def CMDupload(parser, args): | 905 def CMDupload(parser, args): |
| 907 """upload the current changelist to codereview""" | 906 """upload the current changelist to codereview""" |
| 908 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', | 907 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', |
| 909 help='bypass upload presubmit hook') | 908 help='bypass upload presubmit hook') |
| 910 parser.add_option('-f', action='store_true', dest='force', | 909 parser.add_option('-f', action='store_true', dest='force', |
| (...skipping 25 matching lines...) Expand all Loading... |
| 936 cl = Changelist() | 935 cl = Changelist() |
| 937 if args: | 936 if args: |
| 938 base_branch = args[0] | 937 base_branch = args[0] |
| 939 else: | 938 else: |
| 940 # Default to diffing against the "upstream" branch. | 939 # Default to diffing against the "upstream" branch. |
| 941 base_branch = cl.GetUpstreamBranch() | 940 base_branch = cl.GetUpstreamBranch() |
| 942 args = [base_branch + "..."] | 941 args = [base_branch + "..."] |
| 943 | 942 |
| 944 if not options.bypass_hooks and not options.force: | 943 if not options.bypass_hooks and not options.force: |
| 945 hook_results = cl.RunHook(committing=False, upstream_branch=base_branch, | 944 hook_results = cl.RunHook(committing=False, upstream_branch=base_branch, |
| 946 tbr=False, may_prompt=True, | 945 may_prompt=True, |
| 947 verbose=options.verbose, | 946 verbose=options.verbose, |
| 948 author=None) | 947 author=None) |
| 949 if not options.reviewers and hook_results.reviewers: | 948 if not options.reviewers and hook_results.reviewers: |
| 950 options.reviewers = hook_results.reviewers | 949 options.reviewers = hook_results.reviewers |
| 951 | 950 |
| 952 | 951 |
| 953 # --no-ext-diff is broken in some versions of Git, so try to work around | 952 # --no-ext-diff is broken in some versions of Git, so try to work around |
| 954 # this by overriding the environment (but there is still a problem if the | 953 # this by overriding the environment (but there is still a problem if the |
| 955 # git config key "diff.external" is used). | 954 # git config key "diff.external" is used). |
| 956 env = os.environ.copy() | 955 env = os.environ.copy() |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1051 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', | 1050 parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', |
| 1052 help='bypass upload presubmit hook') | 1051 help='bypass upload presubmit hook') |
| 1053 parser.add_option('-m', dest='message', | 1052 parser.add_option('-m', dest='message', |
| 1054 help="override review description") | 1053 help="override review description") |
| 1055 parser.add_option('-f', action='store_true', dest='force', | 1054 parser.add_option('-f', action='store_true', dest='force', |
| 1056 help="force yes to questions (don't prompt)") | 1055 help="force yes to questions (don't prompt)") |
| 1057 parser.add_option('-c', dest='contributor', | 1056 parser.add_option('-c', dest='contributor', |
| 1058 help="external contributor for patch (appended to " + | 1057 help="external contributor for patch (appended to " + |
| 1059 "description and used as author for git). Should be " + | 1058 "description and used as author for git). Should be " + |
| 1060 "formatted as 'First Last <email@example.com>'") | 1059 "formatted as 'First Last <email@example.com>'") |
| 1061 parser.add_option('--tbr', action='store_true', dest='tbr', | |
| 1062 help="short for 'to be reviewed', commit branch " + | |
| 1063 "even without uploading for review") | |
| 1064 (options, args) = parser.parse_args(args) | 1060 (options, args) = parser.parse_args(args) |
| 1065 cl = Changelist() | 1061 cl = Changelist() |
| 1066 | 1062 |
| 1067 if not args or cmd == 'push': | 1063 if not args or cmd == 'push': |
| 1068 # Default to merging against our best guess of the upstream branch. | 1064 # Default to merging against our best guess of the upstream branch. |
| 1069 args = [cl.GetUpstreamBranch()] | 1065 args = [cl.GetUpstreamBranch()] |
| 1070 | 1066 |
| 1071 base_branch = args[0] | 1067 base_branch = args[0] |
| 1072 | 1068 |
| 1073 # Make sure index is up-to-date before running diff-index. | 1069 # Make sure index is up-to-date before running diff-index. |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1093 extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch]) | 1089 extra_commits = RunGit(['rev-list', '^' + svn_head, base_branch]) |
| 1094 if extra_commits: | 1090 if extra_commits: |
| 1095 print ('This branch has %d additional commits not upstreamed yet.' | 1091 print ('This branch has %d additional commits not upstreamed yet.' |
| 1096 % len(extra_commits.splitlines())) | 1092 % len(extra_commits.splitlines())) |
| 1097 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' | 1093 print ('Upstream "%s" or rebase this branch on top of the upstream trunk ' |
| 1098 'before attempting to %s.' % (base_branch, cmd)) | 1094 'before attempting to %s.' % (base_branch, cmd)) |
| 1099 return 1 | 1095 return 1 |
| 1100 | 1096 |
| 1101 if not options.bypass_hooks and not options.force: | 1097 if not options.bypass_hooks and not options.force: |
| 1102 cl.RunHook(committing=True, upstream_branch=base_branch, | 1098 cl.RunHook(committing=True, upstream_branch=base_branch, |
| 1103 tbr=options.tbr, may_prompt=True, verbose=options.verbose, | 1099 may_prompt=True, verbose=options.verbose, |
| 1104 author=options.contributor) | 1100 author=options.contributor) |
| 1105 | 1101 |
| 1106 if cmd == 'dcommit': | 1102 if cmd == 'dcommit': |
| 1107 # Check the tree status if the tree status URL is set. | 1103 # Check the tree status if the tree status URL is set. |
| 1108 status = GetTreeStatus() | 1104 status = GetTreeStatus() |
| 1109 if 'closed' == status: | 1105 if 'closed' == status: |
| 1110 print ('The tree is closed. Please wait for it to reopen. Use ' | 1106 print ('The tree is closed. Please wait for it to reopen. Use ' |
| 1111 '"git cl dcommit -f" to commit on a closed tree.') | 1107 '"git cl dcommit -f" to commit on a closed tree.') |
| 1112 return 1 | 1108 return 1 |
| 1113 elif 'unknown' == status: | 1109 elif 'unknown' == status: |
| 1114 print ('Unable to determine tree status. Please verify manually and ' | 1110 print ('Unable to determine tree status. Please verify manually and ' |
| 1115 'use "git cl dcommit -f" to commit on a closed tree.') | 1111 'use "git cl dcommit -f" to commit on a closed tree.') |
| 1116 | 1112 |
| 1117 description = options.message | 1113 description = options.message |
| 1118 if not options.tbr: | 1114 if not description and cl.GetIssue(): |
| 1119 # It is important to have these checks early. Not only for user | 1115 description = cl.GetDescription() |
| 1120 # convenience, but also because the cl object then caches the correct values | |
| 1121 # of these fields even as we're juggling branches for setting up the commit. | |
| 1122 if not cl.GetIssue(): | |
| 1123 print 'Current issue unknown -- has this branch been uploaded?' | |
| 1124 print 'Use --tbr to commit without review.' | |
| 1125 return 1 | |
| 1126 | 1116 |
| 1127 if not description: | 1117 if not description: |
| 1128 description = cl.GetDescription() | 1118 print 'No description set.' |
| 1119 print 'Visit %s/edit to set it.' % (cl.GetIssueURL()) |
| 1120 return 1 |
| 1129 | 1121 |
| 1130 if not description: | 1122 if cl.GetIssue(): |
| 1131 print 'No description set.' | |
| 1132 print 'Visit %s/edit to set it.' % (cl.GetIssueURL()) | |
| 1133 return 1 | |
| 1134 | |
| 1135 description += "\n\nReview URL: %s" % cl.GetIssueURL() | 1123 description += "\n\nReview URL: %s" % cl.GetIssueURL() |
| 1136 else: | |
| 1137 if not description: | |
| 1138 # Submitting TBR. See if there's already a description in Rietveld, else | |
| 1139 # create a template description. Eitherway, give the user a chance to edit | |
| 1140 # it to fill in the TBR= field. | |
| 1141 if cl.GetIssue(): | |
| 1142 description = cl.GetDescription() | |
| 1143 | |
| 1144 # TODO(dpranke): Update to use ChangeDescription object. | |
| 1145 if not description: | |
| 1146 description = """# Enter a description of the change. | |
| 1147 # This will be used as the change log for the commit. | |
| 1148 | |
| 1149 """ | |
| 1150 description += CreateDescriptionFromLog(args) | |
| 1151 | |
| 1152 description = UserEditedLog(description + '\nTBR=') | |
| 1153 | |
| 1154 if not description: | |
| 1155 print "Description empty; aborting." | |
| 1156 return 1 | |
| 1157 | 1124 |
| 1158 if options.contributor: | 1125 if options.contributor: |
| 1159 if not re.match('^.*\s<\S+@\S+>$', options.contributor): | 1126 if not re.match('^.*\s<\S+@\S+>$', options.contributor): |
| 1160 print "Please provide contibutor as 'First Last <email@example.com>'" | 1127 print "Please provide contibutor as 'First Last <email@example.com>'" |
| 1161 return 1 | 1128 return 1 |
| 1162 description += "\nPatch from %s." % options.contributor | 1129 description += "\nPatch from %s." % options.contributor |
| 1163 print 'Description:', repr(description) | 1130 print 'Description:', repr(description) |
| 1164 | 1131 |
| 1165 branches = [base_branch, cl.GetBranchRef()] | 1132 branches = [base_branch, cl.GetBranchRef()] |
| 1166 if not options.force: | 1133 if not options.force: |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1479 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1446 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 1480 | 1447 |
| 1481 # Not a known command. Default to help. | 1448 # Not a known command. Default to help. |
| 1482 GenUsage(parser, 'help') | 1449 GenUsage(parser, 'help') |
| 1483 return CMDhelp(parser, argv) | 1450 return CMDhelp(parser, argv) |
| 1484 | 1451 |
| 1485 | 1452 |
| 1486 if __name__ == '__main__': | 1453 if __name__ == '__main__': |
| 1487 fix_encoding.fix_encoding() | 1454 fix_encoding.fix_encoding() |
| 1488 sys.exit(main(sys.argv[1:])) | 1455 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |