| Index: git_cl.py
|
| ===================================================================
|
| --- git_cl.py (revision 120273)
|
| +++ git_cl.py (working copy)
|
| @@ -147,6 +147,7 @@
|
| self.viewvc_url = None
|
| self.updated = False
|
| self.did_migrate_check = False
|
| + self.is_gerrit = None
|
|
|
| def LazyUpdateIfNeeded(self):
|
| """Updates the settings from a codereview.settings file, if available."""
|
| @@ -264,6 +265,12 @@
|
| def GetDefaultCCList(self):
|
| return self._GetConfig('rietveld.cc', error_ok=True)
|
|
|
| + def GetIsGerrit(self):
|
| + """Return true if this repo is assosiated with gerrit code review system."""
|
| + if self.is_gerrit is None:
|
| + self.is_gerrit = self._GetConfig('gerrit.host', error_ok=True)
|
| + return self.is_gerrit
|
| +
|
| def _GetConfig(self, param, **kwargs):
|
| self.LazyUpdateIfNeeded()
|
| return RunGit(['config', param], **kwargs).strip()
|
| @@ -604,6 +611,7 @@
|
|
|
| def GetCodereviewSettingsInteractively():
|
| """Prompt the user for settings."""
|
| + # TODO(ukai): ask code review system is rietveld or gerrit?
|
| server = settings.GetDefaultServerUrl(error_ok=True)
|
| prompt = 'Rietveld server (host[:port])'
|
| prompt += ' [%s]' % (server or DEFAULT_SERVER)
|
| @@ -666,9 +674,9 @@
|
| content = re.compile(r'^#.*$', re.MULTILINE).sub('', content).strip()
|
| if not content:
|
| DieWithError('No CL description, aborting')
|
| - self._ParseDescription(content)
|
| + self.ParseDescription(content)
|
|
|
| - def _ParseDescription(self, description):
|
| + def ParseDescription(self, description):
|
| """Updates the list of reviewers and subject from the description."""
|
| if not description:
|
| self.description = description
|
| @@ -723,6 +731,15 @@
|
| SetProperty('tree-status-url', 'STATUS', unset_error_ok=True)
|
| SetProperty('viewvc-url', 'VIEW_VC', unset_error_ok=True)
|
|
|
| + if 'GERRIT_HOST' in keyvals and 'GERRIT_PORT' in keyvals:
|
| + RunGit(['config', 'gerrit.host', keyvals['GERRIT_HOST']])
|
| + RunGit(['config', 'gerrit.port', keyvals['GERRIT_PORT']])
|
| + # Install the standard commit-msg hook.
|
| + RunCommand(['scp', '-p', '-P', keyvals['GERRIT_PORT'],
|
| + '%s:hooks/commit-msg' % keyvals['GERRIT_HOST'],
|
| + os.path.join(settings.GetRoot(),
|
| + '.git', 'hooks', 'commit-msg')])
|
| +
|
| if 'PUSH_URL_CONFIG' in keyvals and 'ORIGIN_URL_CONFIG' in keyvals:
|
| #should be of the form
|
| #PUSH_URL_CONFIG: url.ssh://gitrw.chromium.org.pushinsteadof
|
| @@ -863,64 +880,49 @@
|
| return 0
|
|
|
|
|
| -@usage('[args to "git diff"]')
|
| -def CMDupload(parser, args):
|
| - """upload the current changelist to codereview"""
|
| - parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks',
|
| - help='bypass upload presubmit hook')
|
| - parser.add_option('-f', action='store_true', dest='force',
|
| - help="force yes to questions (don't prompt)")
|
| - parser.add_option('-m', dest='message', help='message for patch')
|
| - parser.add_option('-r', '--reviewers',
|
| - help='reviewer email addresses')
|
| - parser.add_option('--cc',
|
| - help='cc email addresses')
|
| - parser.add_option('--send-mail', action='store_true',
|
| - help='send email to reviewer immediately')
|
| - parser.add_option("--emulate_svn_auto_props", action="store_true",
|
| - dest="emulate_svn_auto_props",
|
| - help="Emulate Subversion's auto properties feature.")
|
| - parser.add_option("--desc_from_logs", action="store_true",
|
| - dest="from_logs",
|
| - help="""Squashes git commit logs into change description and
|
| - uses message as subject""")
|
| - parser.add_option('-c', '--use-commit-queue', action='store_true',
|
| - help='tell the commit queue to commit this patchset')
|
| - (options, args) = parser.parse_args(args)
|
| +def GerritUpload(options, args, cl):
|
| + """upload the current branch to gerrit."""
|
| + # We assume the remote called "origin" is the one we want.
|
| + # It is probably not worthwhile to support different workflows.
|
| + remote = 'origin'
|
| + branch = 'master'
|
| + if options.target_branch:
|
| + branch = options.target_branch
|
|
|
| - # Make sure index is up-to-date before running diff-index.
|
| - RunGit(['update-index', '--refresh', '-q'], error_ok=True)
|
| - if RunGit(['diff-index', 'HEAD']):
|
| - print 'Cannot upload with a dirty tree. You must commit locally first.'
|
| + log_desc = CreateDescriptionFromLog(args)
|
| + if options.reviewers:
|
| + log_desc += '\nR=' + options.reviewers
|
| + change_desc = ChangeDescription(options.message, log_desc,
|
| + options.reviewers)
|
| + change_desc.ParseDescription(log_desc)
|
| + if change_desc.IsEmpty():
|
| + print "Description is empty; aborting."
|
| return 1
|
|
|
| - cl = Changelist()
|
| - if args:
|
| - base_branch = args[0]
|
| - else:
|
| - # Default to diffing against the "upstream" branch.
|
| - base_branch = cl.GetUpstreamBranch()
|
| - args = [base_branch + "..."]
|
| + receive_options = []
|
| + cc = cl.GetCCList().split(',')
|
| + if options.cc:
|
| + cc += options.cc.split(',')
|
| + cc = filter(None, cc)
|
| + if cc:
|
| + receive_options += ['--cc=' + email for email in cc]
|
| + if change_desc.reviewers:
|
| + reviewers = filter(None, change_desc.reviewers.split(','))
|
| + if reviewers:
|
| + receive_options += ['--reviewer=' + email for email in reviewers]
|
|
|
| - if not options.bypass_hooks:
|
| - hook_results = cl.RunHook(committing=False, upstream_branch=base_branch,
|
| - may_prompt=not options.force,
|
| - verbose=options.verbose,
|
| - author=None)
|
| - if not hook_results.should_continue():
|
| - return 1
|
| - if not options.reviewers and hook_results.reviewers:
|
| - options.reviewers = hook_results.reviewers
|
| + git_command = ['push']
|
| + if receive_options:
|
| + git_command.append('--receive-pack="git receive-pack %s"' %
|
| + ' '.join(receive_options))
|
| + git_command += [remote, 'HEAD:refs/for/' + branch]
|
| + RunGit(git_command)
|
| + # TODO(ukai): parse Change-Id: and set issue number?
|
| + return 0
|
|
|
| - # --no-ext-diff is broken in some versions of Git, so try to work around
|
| - # this by overriding the environment (but there is still a problem if the
|
| - # git config key "diff.external" is used).
|
| - env = os.environ.copy()
|
| - if 'GIT_EXTERNAL_DIFF' in env:
|
| - del env['GIT_EXTERNAL_DIFF']
|
| - subprocess2.call(
|
| - ['git', 'diff', '--no-ext-diff', '--stat', '-M'] + args, env=env)
|
|
|
| +def RietveldUpload(options, args, cl):
|
| + """upload the patch to rietveld."""
|
| upload_args = ['--assume_yes'] # Don't ask about untracked files.
|
| upload_args.extend(['--server', cl.GetRietveldServer()])
|
| if options.emulate_svn_auto_props:
|
| @@ -1002,6 +1004,73 @@
|
| return 0
|
|
|
|
|
| +@usage('[args to "git diff"]')
|
| +def CMDupload(parser, args):
|
| + """upload the current changelist to codereview"""
|
| + parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks',
|
| + help='bypass upload presubmit hook')
|
| + parser.add_option('-f', action='store_true', dest='force',
|
| + help="force yes to questions (don't prompt)")
|
| + parser.add_option('-m', dest='message', help='message for patch')
|
| + parser.add_option('-r', '--reviewers',
|
| + help='reviewer email addresses')
|
| + parser.add_option('--cc',
|
| + help='cc email addresses')
|
| + parser.add_option('--send-mail', action='store_true',
|
| + help='send email to reviewer immediately')
|
| + parser.add_option("--emulate_svn_auto_props", action="store_true",
|
| + dest="emulate_svn_auto_props",
|
| + help="Emulate Subversion's auto properties feature.")
|
| + parser.add_option("--desc_from_logs", action="store_true",
|
| + dest="from_logs",
|
| + help="""Squashes git commit logs into change description and
|
| + uses message as subject""")
|
| + parser.add_option('-c', '--use-commit-queue', action='store_true',
|
| + help='tell the commit queue to commit this patchset')
|
| + if settings.GetIsGerrit():
|
| + parser.add_option('--target_branch', dest='target_branch', default='master',
|
| + help='target branch to upload')
|
| + (options, args) = parser.parse_args(args)
|
| +
|
| + # Make sure index is up-to-date before running diff-index.
|
| + RunGit(['update-index', '--refresh', '-q'], error_ok=True)
|
| + if RunGit(['diff-index', 'HEAD']):
|
| + print 'Cannot upload with a dirty tree. You must commit locally first.'
|
| + return 1
|
| +
|
| + cl = Changelist()
|
| + if args:
|
| + # TODO(ukai): is it ok for gerrit case?
|
| + base_branch = args[0]
|
| + else:
|
| + # Default to diffing against the "upstream" branch.
|
| + base_branch = cl.GetUpstreamBranch()
|
| + args = [base_branch + "..."]
|
| +
|
| + if not options.bypass_hooks:
|
| + hook_results = cl.RunHook(committing=False, upstream_branch=base_branch,
|
| + may_prompt=not options.force,
|
| + verbose=options.verbose,
|
| + author=None)
|
| + if not hook_results.should_continue():
|
| + return 1
|
| + if not options.reviewers and hook_results.reviewers:
|
| + options.reviewers = hook_results.reviewers
|
| +
|
| + # --no-ext-diff is broken in some versions of Git, so try to work around
|
| + # this by overriding the environment (but there is still a problem if the
|
| + # git config key "diff.external" is used).
|
| + env = os.environ.copy()
|
| + if 'GIT_EXTERNAL_DIFF' in env:
|
| + del env['GIT_EXTERNAL_DIFF']
|
| + subprocess2.call(
|
| + ['git', 'diff', '--no-ext-diff', '--stat', '-M'] + args, env=env)
|
| +
|
| + if settings.GetIsGerrit():
|
| + return GerritUpload(options, args, cl)
|
| + return RietveldUpload(options, args, cl)
|
| +
|
| +
|
| def SendUpstream(parser, args, cmd):
|
| """Common code for CmdPush and CmdDCommit
|
|
|
| @@ -1229,6 +1298,7 @@
|
| issue_arg = args[0]
|
|
|
| # TODO(maruel): Use apply_issue.py
|
| + # TODO(ukai): use gerrit-cherry-pick for gerrit repository?
|
|
|
| if re.match(r'\d+', issue_arg):
|
| # Input is an issue id. Figure out the URL.
|
|
|