Chromium Code Reviews| 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 import json | 10 import json |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 127 # Parse specs like "trunk/src:refs/remotes/origin/trunk". | 127 # Parse specs like "trunk/src:refs/remotes/origin/trunk". |
| 128 if fetch_suburl: | 128 if fetch_suburl: |
| 129 full_url = base_url + '/' + fetch_suburl | 129 full_url = base_url + '/' + fetch_suburl |
| 130 else: | 130 else: |
| 131 full_url = base_url | 131 full_url = base_url |
| 132 if full_url == url: | 132 if full_url == url: |
| 133 return as_ref | 133 return as_ref |
| 134 return None | 134 return None |
| 135 | 135 |
| 136 | 136 |
| 137 def print_stats(args): | 137 def print_stats(options, args): |
| 138 """Prints statistics about the change to the user.""" | 138 """Prints statistics about the change to the user.""" |
| 139 # --no-ext-diff is broken in some versions of Git, so try to work around | 139 # --no-ext-diff is broken in some versions of Git, so try to work around |
| 140 # this by overriding the environment (but there is still a problem if the | 140 # this by overriding the environment (but there is still a problem if the |
| 141 # git config key "diff.external" is used). | 141 # git config key "diff.external" is used). |
| 142 env = os.environ.copy() | 142 env = os.environ.copy() |
| 143 if 'GIT_EXTERNAL_DIFF' in env: | 143 if 'GIT_EXTERNAL_DIFF' in env: |
| 144 del env['GIT_EXTERNAL_DIFF'] | 144 del env['GIT_EXTERNAL_DIFF'] |
| 145 return subprocess2.call( | 145 return subprocess2.call( |
| 146 ['git', 'diff', '--no-ext-diff', '--stat', '--find-copies-harder', | 146 ['git', 'diff', '--no-ext-diff', '--stat', '--find-copies-harder', |
| 147 '-l100000'] + args, env=env) | 147 '-C%s' % options.git_similarity, '-l100000'] + args, env=env) |
| 148 | 148 |
| 149 | 149 |
| 150 class Settings(object): | 150 class Settings(object): |
| 151 def __init__(self): | 151 def __init__(self): |
| 152 self.default_server = None | 152 self.default_server = None |
| 153 self.cc = None | 153 self.cc = None |
| 154 self.root = None | 154 self.root = None |
| 155 self.is_git_svn = None | 155 self.is_git_svn = None |
| 156 self.svn_branch = None | 156 self.svn_branch = None |
| 157 self.tree_status_url = None | 157 self.tree_status_url = None |
| (...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1030 if change_desc.reviewers: | 1030 if change_desc.reviewers: |
| 1031 upload_args.extend(['--reviewers', change_desc.reviewers]) | 1031 upload_args.extend(['--reviewers', change_desc.reviewers]) |
| 1032 if options.send_mail: | 1032 if options.send_mail: |
| 1033 if not change_desc.reviewers: | 1033 if not change_desc.reviewers: |
| 1034 DieWithError("Must specify reviewers to send email.") | 1034 DieWithError("Must specify reviewers to send email.") |
| 1035 upload_args.append('--send_mail') | 1035 upload_args.append('--send_mail') |
| 1036 cc = ','.join(filter(None, (cl.GetCCList(), options.cc))) | 1036 cc = ','.join(filter(None, (cl.GetCCList(), options.cc))) |
| 1037 if cc: | 1037 if cc: |
| 1038 upload_args.extend(['--cc', cc]) | 1038 upload_args.extend(['--cc', cc]) |
| 1039 | 1039 |
| 1040 upload_args.extend(['--git_similarity', str(options.git_similarity)]) | |
| 1041 | |
| 1040 # Include the upstream repo's URL in the change -- this is useful for | 1042 # Include the upstream repo's URL in the change -- this is useful for |
| 1041 # projects that have their source spread across multiple repos. | 1043 # projects that have their source spread across multiple repos. |
| 1042 remote_url = cl.GetGitBaseUrlFromConfig() | 1044 remote_url = cl.GetGitBaseUrlFromConfig() |
| 1043 if not remote_url: | 1045 if not remote_url: |
| 1044 if settings.GetIsGitSvn(): | 1046 if settings.GetIsGitSvn(): |
| 1045 # URL is dependent on the current directory. | 1047 # URL is dependent on the current directory. |
| 1046 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) | 1048 data = RunGit(['svn', 'info'], cwd=settings.GetRoot()) |
| 1047 if data: | 1049 if data: |
| 1048 keys = dict(line.split(': ', 1) for line in data.splitlines() | 1050 keys = dict(line.split(': ', 1) for line in data.splitlines() |
| 1049 if ': ' in line) | 1051 if ': ' in line) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1131 if not options.bypass_hooks: | 1133 if not options.bypass_hooks: |
| 1132 hook_results = cl.RunHook(committing=False, upstream_branch=base_branch, | 1134 hook_results = cl.RunHook(committing=False, upstream_branch=base_branch, |
| 1133 may_prompt=not options.force, | 1135 may_prompt=not options.force, |
| 1134 verbose=options.verbose, | 1136 verbose=options.verbose, |
| 1135 author=None) | 1137 author=None) |
| 1136 if not hook_results.should_continue(): | 1138 if not hook_results.should_continue(): |
| 1137 return 1 | 1139 return 1 |
| 1138 if not options.reviewers and hook_results.reviewers: | 1140 if not options.reviewers and hook_results.reviewers: |
| 1139 options.reviewers = hook_results.reviewers | 1141 options.reviewers = hook_results.reviewers |
| 1140 | 1142 |
| 1141 print_stats(args) | 1143 print_stats(options, args) |
| 1142 if settings.GetIsGerrit(): | 1144 if settings.GetIsGerrit(): |
| 1143 return GerritUpload(options, args, cl) | 1145 return GerritUpload(options, args, cl) |
| 1144 return RietveldUpload(options, args, cl) | 1146 return RietveldUpload(options, args, cl) |
| 1145 | 1147 |
| 1146 | 1148 |
| 1147 def IsSubmoduleMergeCommit(ref): | 1149 def IsSubmoduleMergeCommit(ref): |
| 1148 # When submodules are added to the repo, we expect there to be a single | 1150 # When submodules are added to the repo, we expect there to be a single |
| 1149 # non-git-svn merge commit at remote HEAD with a signature comment. | 1151 # non-git-svn merge commit at remote HEAD with a signature comment. |
| 1150 pattern = '^SVN changes up to revision [0-9]*$' | 1152 pattern = '^SVN changes up to revision [0-9]*$' |
| 1151 cmd = ['rev-list', '--merges', '--grep=%s' % pattern, '%s^!' % ref] | 1153 cmd = ['rev-list', '--merges', '--grep=%s' % pattern, '%s^!' % ref] |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1264 | 1266 |
| 1265 if cl.GetIssue(): | 1267 if cl.GetIssue(): |
| 1266 description += "\n\nReview URL: %s" % cl.GetIssueURL() | 1268 description += "\n\nReview URL: %s" % cl.GetIssueURL() |
| 1267 | 1269 |
| 1268 if options.contributor: | 1270 if options.contributor: |
| 1269 description += "\nPatch from %s." % options.contributor | 1271 description += "\nPatch from %s." % options.contributor |
| 1270 print 'Description:', repr(description) | 1272 print 'Description:', repr(description) |
| 1271 | 1273 |
| 1272 branches = [base_branch, cl.GetBranchRef()] | 1274 branches = [base_branch, cl.GetBranchRef()] |
| 1273 if not options.force: | 1275 if not options.force: |
| 1274 print_stats(branches) | 1276 print_stats(options, branches) |
| 1275 ask_for_data('About to commit; enter to confirm.') | 1277 ask_for_data('About to commit; enter to confirm.') |
| 1276 | 1278 |
| 1277 # We want to squash all this branch's commits into one commit with the proper | 1279 # We want to squash all this branch's commits into one commit with the proper |
| 1278 # description. We do this by doing a "reset --soft" to the base branch (which | 1280 # description. We do this by doing a "reset --soft" to the base branch (which |
| 1279 # keeps the working copy the same), then dcommitting that. If origin/master | 1281 # keeps the working copy the same), then dcommitting that. If origin/master |
| 1280 # has a submodule merge commit, we'll also need to cherry-pick the squashed | 1282 # has a submodule merge commit, we'll also need to cherry-pick the squashed |
| 1281 # commit onto a branch based on the git-svn head. | 1283 # commit onto a branch based on the git-svn head. |
| 1282 MERGE_BRANCH = 'git-cl-commit' | 1284 MERGE_BRANCH = 'git-cl-commit' |
| 1283 CHERRY_PICK_BRANCH = 'git-cl-cherry-pick' | 1285 CHERRY_PICK_BRANCH = 'git-cl-cherry-pick' |
| 1284 # Delete the branches if they exist. | 1286 # Delete the branches if they exist. |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1313 RunGit(['cherry-pick', cherry_pick_commit]) | 1315 RunGit(['cherry-pick', cherry_pick_commit]) |
| 1314 if cmd == 'push': | 1316 if cmd == 'push': |
| 1315 # push the merge branch. | 1317 # push the merge branch. |
| 1316 remote, branch = cl.FetchUpstreamTuple() | 1318 remote, branch = cl.FetchUpstreamTuple() |
| 1317 retcode, output = RunGitWithCode( | 1319 retcode, output = RunGitWithCode( |
| 1318 ['push', '--porcelain', remote, 'HEAD:%s' % branch]) | 1320 ['push', '--porcelain', remote, 'HEAD:%s' % branch]) |
| 1319 logging.debug(output) | 1321 logging.debug(output) |
| 1320 else: | 1322 else: |
| 1321 # dcommit the merge branch. | 1323 # dcommit the merge branch. |
| 1322 retcode, output = RunGitWithCode(['svn', 'dcommit', | 1324 retcode, output = RunGitWithCode(['svn', 'dcommit', |
| 1325 '-C%s' % options.git_similarity, | |
| 1323 '--no-rebase', '--rmdir']) | 1326 '--no-rebase', '--rmdir']) |
| 1324 finally: | 1327 finally: |
| 1325 # And then swap back to the original branch and clean up. | 1328 # And then swap back to the original branch and clean up. |
| 1326 RunGit(['checkout', '-q', cl.GetBranch()]) | 1329 RunGit(['checkout', '-q', cl.GetBranch()]) |
| 1327 RunGit(['branch', '-D', MERGE_BRANCH]) | 1330 RunGit(['branch', '-D', MERGE_BRANCH]) |
| 1328 if base_has_submodules: | 1331 if base_has_submodules: |
| 1329 RunGit(['branch', '-D', CHERRY_PICK_BRANCH]) | 1332 RunGit(['branch', '-D', CHERRY_PICK_BRANCH]) |
| 1330 | 1333 |
| 1331 if cl.GetIssue(): | 1334 if cl.GetIssue(): |
| 1332 if cmd == 'dcommit' and 'Committed r' in output: | 1335 if cmd == 'dcommit' and 'Committed r' in output: |
| (...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1670 # Do it late so all commands are listed. | 1673 # Do it late so all commands are listed. |
| 1671 CMDhelp.usage_more = ('\n\nCommands are:\n' + '\n'.join([ | 1674 CMDhelp.usage_more = ('\n\nCommands are:\n' + '\n'.join([ |
| 1672 ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) | 1675 ' %-10s %s' % (fn[3:], Command(fn[3:]).__doc__.split('\n')[0].strip()) |
| 1673 for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) | 1676 for fn in dir(sys.modules[__name__]) if fn.startswith('CMD')])) |
| 1674 | 1677 |
| 1675 # Create the option parse and add --verbose support. | 1678 # Create the option parse and add --verbose support. |
| 1676 parser = optparse.OptionParser() | 1679 parser = optparse.OptionParser() |
| 1677 parser.add_option( | 1680 parser.add_option( |
| 1678 '-v', '--verbose', action='count', default=0, | 1681 '-v', '--verbose', action='count', default=0, |
| 1679 help='Use 2 times for more debugging info') | 1682 help='Use 2 times for more debugging info') |
| 1683 parser.add_option( | |
| 1684 '-C', '-M', '--git_similarity', '--find-copies-harder', type='int', | |
|
cmp
2012/09/18 01:44:15
let's call this just --similarity to keep it simpl
| |
| 1685 dest='git_similarity', action='store', metavar='SIM', default=50, | |
| 1686 help='Sets the percentage that a pair of files need to match in order to' | |
| 1687 ' be considered copies (default 50)') | |
|
cmp
2012/09/18 01:44:15
please note here that this is only used for Git (n
| |
| 1680 old_parser_args = parser.parse_args | 1688 old_parser_args = parser.parse_args |
| 1681 def Parse(args): | 1689 def Parse(args): |
| 1682 options, args = old_parser_args(args) | 1690 options, args = old_parser_args(args) |
| 1683 if options.verbose >= 2: | 1691 if options.verbose >= 2: |
| 1684 logging.basicConfig(level=logging.DEBUG) | 1692 logging.basicConfig(level=logging.DEBUG) |
| 1685 elif options.verbose: | 1693 elif options.verbose: |
| 1686 logging.basicConfig(level=logging.INFO) | 1694 logging.basicConfig(level=logging.INFO) |
| 1687 else: | 1695 else: |
| 1688 logging.basicConfig(level=logging.WARNING) | 1696 logging.basicConfig(level=logging.WARNING) |
| 1689 return options, args | 1697 return options, args |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 1704 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) | 1712 'and retry or visit go/isgaeup.\n%s') % (e.code, str(e))) |
| 1705 | 1713 |
| 1706 # Not a known command. Default to help. | 1714 # Not a known command. Default to help. |
| 1707 GenUsage(parser, 'help') | 1715 GenUsage(parser, 'help') |
| 1708 return CMDhelp(parser, argv) | 1716 return CMDhelp(parser, argv) |
| 1709 | 1717 |
| 1710 | 1718 |
| 1711 if __name__ == '__main__': | 1719 if __name__ == '__main__': |
| 1712 fix_encoding.fix_encoding() | 1720 fix_encoding.fix_encoding() |
| 1713 sys.exit(main(sys.argv[1:])) | 1721 sys.exit(main(sys.argv[1:])) |
| OLD | NEW |