| Index: git_cl.py
|
| diff --git a/git_cl.py b/git_cl.py
|
| index ad6fe01a2e0e38437b724c5e4a0fbc8548a73fe7..9d7ba02b1b90ee8b2f456b5f7ef0cbe1be824f32 100755
|
| --- a/git_cl.py
|
| +++ b/git_cl.py
|
| @@ -1426,6 +1426,10 @@ class _ChangelistCodereviewBase(object):
|
| failed."""
|
| raise NotImplementedError()
|
|
|
| + def CMDUploadChange(self, options, args, change):
|
| + """Uploads a change to codereview."""
|
| + raise NotImplementedError()
|
| +
|
|
|
| class _RietveldChangelistImpl(_ChangelistCodereviewBase):
|
| def __init__(self, changelist, auth_config=None, rietveld_server=None):
|
| @@ -1438,9 +1442,6 @@ class _RietveldChangelistImpl(_ChangelistCodereviewBase):
|
| self._props = None
|
| self._rpc_server = None
|
|
|
| - def GetAuthConfig(self):
|
| - return self._auth_config
|
| -
|
| def GetCodereviewServer(self):
|
| if not self._rietveld_server:
|
| # If we're on a branch then get the server potentially associated
|
| @@ -1687,6 +1688,158 @@ class _RietveldChangelistImpl(_ChangelistCodereviewBase):
|
| patch_url=gclient_utils.UpgradeToHttps(parsed_url.geturl()))
|
| return None
|
|
|
| + def CMDUploadChange(self, options, args, change):
|
| + """Upload the patch to Rietveld."""
|
| + upload_args = ['--assume_yes'] # Don't ask about untracked files.
|
| + upload_args.extend(['--server', self.GetCodereviewServer()])
|
| + # TODO(tandrii): refactor this ugliness into _RietveldChangelistImpl.
|
| + upload_args.extend(auth.auth_config_to_command_options(self._auth_config))
|
| + if options.emulate_svn_auto_props:
|
| + upload_args.append('--emulate_svn_auto_props')
|
| +
|
| + change_desc = None
|
| +
|
| + if options.email is not None:
|
| + upload_args.extend(['--email', options.email])
|
| +
|
| + if self.GetIssue():
|
| + if options.title:
|
| + upload_args.extend(['--title', options.title])
|
| + if options.message:
|
| + upload_args.extend(['--message', options.message])
|
| + upload_args.extend(['--issue', str(self.GetIssue())])
|
| + print ('This branch is associated with issue %s. '
|
| + 'Adding patch to that issue.' % self.GetIssue())
|
| + else:
|
| + if options.title:
|
| + upload_args.extend(['--title', options.title])
|
| + message = (options.title or options.message or
|
| + CreateDescriptionFromLog(args))
|
| + change_desc = ChangeDescription(message)
|
| + if options.reviewers or options.tbr_owners:
|
| + change_desc.update_reviewers(options.reviewers,
|
| + options.tbr_owners,
|
| + change)
|
| + if not options.force:
|
| + change_desc.prompt()
|
| +
|
| + if not change_desc.description:
|
| + print "Description is empty; aborting."
|
| + return 1
|
| +
|
| + upload_args.extend(['--message', change_desc.description])
|
| + if change_desc.get_reviewers():
|
| + upload_args.append('--reviewers=%s' % ','.join(
|
| + change_desc.get_reviewers()))
|
| + if options.send_mail:
|
| + if not change_desc.get_reviewers():
|
| + DieWithError("Must specify reviewers to send email.")
|
| + upload_args.append('--send_mail')
|
| +
|
| + # We check this before applying rietveld.private assuming that in
|
| + # rietveld.cc only addresses which we can send private CLs to are listed
|
| + # if rietveld.private is set, and so we should ignore rietveld.cc only
|
| + # when --private is specified explicitly on the command line.
|
| + if options.private:
|
| + logging.warn('rietveld.cc is ignored since private flag is specified. '
|
| + 'You need to review and add them manually if necessary.')
|
| + cc = self.GetCCListWithoutDefault()
|
| + else:
|
| + cc = self.GetCCList()
|
| + cc = ','.join(filter(None, (cc, ','.join(options.cc))))
|
| + if cc:
|
| + upload_args.extend(['--cc', cc])
|
| +
|
| + if options.private or settings.GetDefaultPrivateFlag() == "True":
|
| + upload_args.append('--private')
|
| +
|
| + upload_args.extend(['--git_similarity', str(options.similarity)])
|
| + if not options.find_copies:
|
| + upload_args.extend(['--git_no_find_copies'])
|
| +
|
| + # Include the upstream repo's URL in the change -- this is useful for
|
| + # projects that have their source spread across multiple repos.
|
| + remote_url = self.GetGitBaseUrlFromConfig()
|
| + if not remote_url:
|
| + if settings.GetIsGitSvn():
|
| + remote_url = self.GetGitSvnRemoteUrl()
|
| + else:
|
| + if self.GetRemoteUrl() and '/' in self.GetUpstreamBranch():
|
| + remote_url = '%s@%s' % (self.GetRemoteUrl(),
|
| + self.GetUpstreamBranch().split('/')[-1])
|
| + if remote_url:
|
| + upload_args.extend(['--base_url', remote_url])
|
| + remote, remote_branch = self.GetRemoteBranch()
|
| + target_ref = GetTargetRef(remote, remote_branch, options.target_branch,
|
| + settings.GetPendingRefPrefix())
|
| + if target_ref:
|
| + upload_args.extend(['--target_ref', target_ref])
|
| +
|
| + # Look for dependent patchsets. See crbug.com/480453 for more details.
|
| + remote, upstream_branch = self.FetchUpstreamTuple(self.GetBranch())
|
| + upstream_branch = ShortBranchName(upstream_branch)
|
| + if remote is '.':
|
| + # A local branch is being tracked.
|
| + local_branch = ShortBranchName(upstream_branch)
|
| + if settings.GetIsSkipDependencyUpload(local_branch):
|
| + print
|
| + print ('Skipping dependency patchset upload because git config '
|
| + 'branch.%s.skip-deps-uploads is set to True.' % local_branch)
|
| + print
|
| + else:
|
| + auth_config = auth.extract_auth_config_from_options(options)
|
| + branch_cl = Changelist(branchref=local_branch,
|
| + auth_config=auth_config)
|
| + branch_cl_issue_url = branch_cl.GetIssueURL()
|
| + branch_cl_issue = branch_cl.GetIssue()
|
| + branch_cl_patchset = branch_cl.GetPatchset()
|
| + if branch_cl_issue_url and branch_cl_issue and branch_cl_patchset:
|
| + upload_args.extend(
|
| + ['--depends_on_patchset', '%s:%s' % (
|
| + branch_cl_issue, branch_cl_patchset)])
|
| + print (
|
| + '\n'
|
| + 'The current branch (%s) is tracking a local branch (%s) with '
|
| + 'an associated CL.\n'
|
| + 'Adding %s/#ps%s as a dependency patchset.\n'
|
| + '\n' % (self.GetBranch(), local_branch, branch_cl_issue_url,
|
| + branch_cl_patchset))
|
| +
|
| + project = settings.GetProject()
|
| + if project:
|
| + upload_args.extend(['--project', project])
|
| +
|
| + if options.cq_dry_run:
|
| + upload_args.extend(['--cq_dry_run'])
|
| +
|
| + try:
|
| + upload_args = ['upload'] + upload_args + args
|
| + logging.info('upload.RealMain(%s)', upload_args)
|
| + issue, patchset = upload.RealMain(upload_args)
|
| + issue = int(issue)
|
| + patchset = int(patchset)
|
| + except KeyboardInterrupt:
|
| + sys.exit(1)
|
| + except:
|
| + # If we got an exception after the user typed a description for their
|
| + # change, back up the description before re-raising.
|
| + if change_desc:
|
| + backup_path = os.path.expanduser(DESCRIPTION_BACKUP_FILE)
|
| + print('\nGot exception while uploading -- saving description to %s\n' %
|
| + backup_path)
|
| + backup_file = open(backup_path, 'w')
|
| + backup_file.write(change_desc.description)
|
| + backup_file.close()
|
| + raise
|
| +
|
| + if not self.GetIssue():
|
| + self.SetIssue(issue)
|
| + self.SetPatchset(patchset)
|
| +
|
| + if options.use_commit_queue:
|
| + self.SetFlag('commit', '1')
|
| + return 0
|
| +
|
|
|
| class _GerritChangelistImpl(_ChangelistCodereviewBase):
|
| def __init__(self, changelist, auth_config=None):
|
| @@ -1826,9 +1979,11 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
|
| gerrit_util.SubmitChange(self._GetGerritHost(), self.GetIssue(),
|
| wait_for_merge=wait_for_merge)
|
|
|
| - def _GetChangeDetail(self, options):
|
| - return gerrit_util.GetChangeDetail(self._GetGerritHost(), self.GetIssue(),
|
| - options)
|
| + def _GetChangeDetail(self, options=None, issue=None):
|
| + options = options or []
|
| + issue = issue or self.GetIssue()
|
| + assert issue, 'issue required to query Gerrit'
|
| + return gerrit_util.GetChangeDetail(self._GetGerritHost(), options, issue)
|
|
|
| def CMDLand(self, force, bypass_hooks, verbose):
|
| if git_common.is_dirty_git_tree('land'):
|
| @@ -1922,6 +2077,206 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
|
| hostname=parsed_url.netloc)
|
| return None
|
|
|
| + def CMDUploadChange(self, options, args, change):
|
| + """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.
|
| + gerrit_remote = 'origin'
|
| +
|
| + remote, remote_branch = self.GetRemoteBranch()
|
| + branch = GetTargetRef(remote, remote_branch, options.target_branch,
|
| + pending_prefix='')
|
| +
|
| + if options.title:
|
| + # TODO(tandrii): it's now supported by Gerrit, implement!
|
| + print "\nPatch titles (-t) are not supported in Gerrit. Aborting..."
|
| + return 1
|
| +
|
| + if options.squash:
|
| + if not self.GetIssue():
|
| + # TODO(tandrii): deperecate this after 2016Q2. Backwards compatibility
|
| + # with shadow branch, which used to contain change-id for a given
|
| + # branch, using which we can fetch actual issue number and set it as the
|
| + # property of the branch, which is the new way.
|
| + message = RunGitSilent([
|
| + 'show', '--format=%B', '-s',
|
| + 'refs/heads/git_cl_uploads/%s' % self.GetBranch()])
|
| + if message:
|
| + change_ids = git_footers.get_footer_change_id(message.strip())
|
| + if change_ids and len(change_ids) == 1:
|
| + details = self._GetChangeDetail(issue=change_ids[0])
|
| + if details:
|
| + print('WARNING: found old upload in branch git_cl_uploads/%s '
|
| + 'corresponding to issue %s' %
|
| + (self.GetBranch(), details['_number']))
|
| + self.SetIssue(details['_number'])
|
| + if not self.GetIssue():
|
| + DieWithError(
|
| + '\n' # For readability of the blob below.
|
| + 'Found old upload in branch git_cl_uploads/%s, '
|
| + 'but failed to find corresponding Gerrit issue.\n'
|
| + 'If you know the issue number, set it manually first:\n'
|
| + ' git cl issue 123456\n'
|
| + 'If you intended to upload this CL as new issue, '
|
| + 'just delete or rename the old upload branch:\n'
|
| + ' git rename-branch git_cl_uploads/%s old_upload-%s\n'
|
| + 'After that, please run git cl upload again.' %
|
| + tuple([self.GetBranch()] * 3))
|
| + # End of backwards compatability.
|
| +
|
| + if self.GetIssue():
|
| + # Try to get the message from a previous upload.
|
| + message = self.GetDescription()
|
| + if not message:
|
| + DieWithError(
|
| + 'failed to fetch description from current Gerrit issue %d\n'
|
| + '%s' % (self.GetIssue(), self.GetIssueURL()))
|
| + change_id = self._GetChangeDetail()['change_id']
|
| + while True:
|
| + footer_change_ids = git_footers.get_footer_change_id(message)
|
| + if footer_change_ids == [change_id]:
|
| + break
|
| + if not footer_change_ids:
|
| + message = git_footers.add_footer_change_id(message, change_id)
|
| + print('WARNING: appended missing Change-Id to issue description')
|
| + continue
|
| + # There is already a valid footer but with different or several ids.
|
| + # Doing this automatically is non-trivial as we don't want to lose
|
| + # existing other footers, yet we want to append just 1 desired
|
| + # Change-Id. Thus, just create a new footer, but let user verify the
|
| + # new description.
|
| + message = '%s\n\nChange-Id: %s' % (message, change_id)
|
| + print(
|
| + 'WARNING: issue %s has Change-Id footer(s):\n'
|
| + ' %s\n'
|
| + 'but issue has Change-Id %s, according to Gerrit.\n'
|
| + 'Please, check the proposed correction to the description, '
|
| + 'and edit it if necessary but keep the "Change-Id: %s" footer\n'
|
| + % (self.GetIssue(), '\n '.join(footer_change_ids), change_id,
|
| + change_id))
|
| + ask_for_data('Press enter to edit now, Ctrl+C to abort')
|
| + if not options.force:
|
| + change_desc = ChangeDescription(message)
|
| + change_desc.prompt()
|
| + message = change_desc.description
|
| + if not message:
|
| + DieWithError("Description is empty. Aborting...")
|
| + # Continue the while loop.
|
| + # Sanity check of this code - we should end up with proper message
|
| + # footer.
|
| + assert [change_id] == git_footers.get_footer_change_id(message)
|
| + change_desc = ChangeDescription(message)
|
| + else:
|
| + change_desc = ChangeDescription(
|
| + options.message or CreateDescriptionFromLog(args))
|
| + if not options.force:
|
| + change_desc.prompt()
|
| + if not change_desc.description:
|
| + DieWithError("Description is empty. Aborting...")
|
| + message = change_desc.description
|
| + change_ids = git_footers.get_footer_change_id(message)
|
| + if len(change_ids) > 1:
|
| + DieWithError('too many Change-Id footers, at most 1 allowed.')
|
| + if not change_ids:
|
| + # Generate the Change-Id automatically.
|
| + message = git_footers.add_footer_change_id(
|
| + message, GenerateGerritChangeId(message))
|
| + change_desc.set_description(message)
|
| + change_ids = git_footers.get_footer_change_id(message)
|
| + assert len(change_ids) == 1
|
| + change_id = change_ids[0]
|
| +
|
| + remote, upstream_branch = self.FetchUpstreamTuple(self.GetBranch())
|
| + if remote is '.':
|
| + # If our upstream branch is local, we base our squashed commit on its
|
| + # squashed version.
|
| + upstream_branch_name = scm.GIT.ShortBranchName(upstream_branch)
|
| + # Check the squashed hash of the parent.
|
| + parent = RunGit(['config',
|
| + 'branch.%s.gerritsquashhash' % upstream_branch_name],
|
| + error_ok=True).strip()
|
| + # Verify that the upstream branch has been uploaded too, otherwise
|
| + # Gerrit will create additional CLs when uploading.
|
| + if not parent or (RunGitSilent(['rev-parse', upstream_branch + ':']) !=
|
| + RunGitSilent(['rev-parse', parent + ':'])):
|
| + # TODO(tandrii): remove "old depot_tools" part on April 12, 2016.
|
| + DieWithError(
|
| + 'Upload upstream branch %s first.\n'
|
| + 'Note: maybe you\'ve uploaded it with --no-squash or with an old '
|
| + 'version of depot_tools. If so, then re-upload it with:\n'
|
| + ' git cl upload --squash\n' % upstream_branch_name)
|
| + else:
|
| + parent = self.GetCommonAncestorWithUpstream()
|
| +
|
| + tree = RunGit(['rev-parse', 'HEAD:']).strip()
|
| + ref_to_push = RunGit(['commit-tree', tree, '-p', parent,
|
| + '-m', message]).strip()
|
| + else:
|
| + change_desc = ChangeDescription(
|
| + options.message or CreateDescriptionFromLog(args))
|
| + if not change_desc.description:
|
| + DieWithError("Description is empty. Aborting...")
|
| +
|
| + if not git_footers.get_footer_change_id(change_desc.description):
|
| + DownloadGerritHook(False)
|
| + change_desc.set_description(AddChangeIdToCommitMessage(options, args))
|
| + ref_to_push = 'HEAD'
|
| + parent = '%s/%s' % (gerrit_remote, branch)
|
| + change_id = git_footers.get_footer_change_id(change_desc.description)[0]
|
| +
|
| + assert change_desc
|
| + commits = RunGitSilent(['rev-list', '%s..%s' % (parent,
|
| + ref_to_push)]).splitlines()
|
| + if len(commits) > 1:
|
| + print('WARNING: This will upload %d commits. Run the following command '
|
| + 'to see which commits will be uploaded: ' % len(commits))
|
| + print('git log %s..%s' % (parent, ref_to_push))
|
| + print('You can also use `git squash-branch` to squash these into a '
|
| + 'single commit.')
|
| + ask_for_data('About to upload; enter to confirm.')
|
| +
|
| + if options.reviewers or options.tbr_owners:
|
| + change_desc.update_reviewers(options.reviewers, options.tbr_owners,
|
| + change)
|
| +
|
| + receive_options = []
|
| + cc = self.GetCCList().split(',')
|
| + if options.cc:
|
| + cc.extend(options.cc)
|
| + cc = filter(None, cc)
|
| + if cc:
|
| + receive_options += ['--cc=' + email for email in cc]
|
| + if change_desc.get_reviewers():
|
| + receive_options.extend(
|
| + '--reviewer=' + email for email in change_desc.get_reviewers())
|
| +
|
| + git_command = ['push']
|
| + if receive_options:
|
| + git_command.append('--receive-pack=git receive-pack %s' %
|
| + ' '.join(receive_options))
|
| + git_command += [gerrit_remote, ref_to_push + ':refs/for/' + branch]
|
| + push_stdout = gclient_utils.CheckCallAndFilter(
|
| + ['git'] + git_command,
|
| + print_stdout=True,
|
| + # Flush after every line: useful for seeing progress when running as
|
| + # recipe.
|
| + filter_fn=lambda _: sys.stdout.flush())
|
| +
|
| + if options.squash:
|
| + regex = re.compile(r'remote:\s+https?://[\w\-\.\/]*/(\d+)\s.*')
|
| + change_numbers = [m.group(1)
|
| + for m in map(regex.match, push_stdout.splitlines())
|
| + if m]
|
| + if len(change_numbers) != 1:
|
| + DieWithError(
|
| + ('Created|Updated %d issues on Gerrit, but only 1 expected.\n'
|
| + 'Change-Id: %s') % (len(change_numbers), change_id))
|
| + self.SetIssue(change_numbers[0])
|
| + RunGit(['config', 'branch.%s.gerritsquashhash' % self.GetBranch(),
|
| + ref_to_push])
|
| + return 0
|
| +
|
| +
|
|
|
| _CODEREVIEW_IMPLEMENTATIONS = {
|
| 'rietveld': _RietveldChangelistImpl,
|
| @@ -2794,206 +3149,6 @@ def GenerateGerritChangeId(message):
|
| return 'I%s' % change_hash.strip()
|
|
|
|
|
| -def GerritUpload(options, args, cl, change):
|
| - """upload the current branch to gerrit."""
|
| - # TODO(tandrii): refactor this to be a method of _GerritChangelistImpl,
|
| - # to avoid private members accessors below.
|
| -
|
| - # We assume the remote called "origin" is the one we want.
|
| - # It is probably not worthwhile to support different workflows.
|
| - gerrit_remote = 'origin'
|
| -
|
| - remote, remote_branch = cl.GetRemoteBranch()
|
| - branch = GetTargetRef(remote, remote_branch, options.target_branch,
|
| - pending_prefix='')
|
| -
|
| - if options.title:
|
| - print "\nPatch titles (-t) are not supported in Gerrit. Aborting..."
|
| - return 1
|
| -
|
| - if options.squash:
|
| - if not cl.GetIssue():
|
| - # TODO(tandrii): deperecate this after 2016Q2.
|
| - # Backwards compatibility with shadow branch, which used to contain
|
| - # change-id for a given branch, using which we can fetch actual issue
|
| - # number and set it as the property of the branch, which is the new way.
|
| - message = RunGitSilent(['show', '--format=%B', '-s',
|
| - 'refs/heads/git_cl_uploads/%s' % cl.GetBranch()])
|
| - if message:
|
| - change_ids = git_footers.get_footer_change_id(message.strip())
|
| - if change_ids and len(change_ids) == 1:
|
| - details = gerrit_util.GetChangeDetail(
|
| - cl._codereview_impl._GetGerritHost(), change_ids[0])
|
| - if details:
|
| - print('WARNING: found old upload in branch git_cl_uploads/%s '
|
| - 'corresponding to issue %s' %
|
| - (cl.GetBranch(), details['_number']))
|
| - cl.SetIssue(details['_number'])
|
| - if not cl.GetIssue():
|
| - DieWithError(
|
| - '\n' # For readability of the blob below.
|
| - 'Found old upload in branch git_cl_uploads/%s, '
|
| - 'but failed to find corresponding Gerrit issue.\n'
|
| - 'If you know the issue number, set it manually first:\n'
|
| - ' git cl issue 123456\n'
|
| - 'If you intended to upload this CL as new issue, '
|
| - 'just delete or rename the old upload branch:\n'
|
| - ' git rename-branch git_cl_uploads/%s old_upload-%s\n'
|
| - 'After that, please run git cl upload again.' %
|
| - tuple([cl.GetBranch()] * 3))
|
| - # End of backwards compatability.
|
| -
|
| - if cl.GetIssue():
|
| - # Try to get the message from a previous upload.
|
| - message = cl.GetDescription()
|
| - if not message:
|
| - DieWithError(
|
| - 'failed to fetch description from current Gerrit issue %d\n'
|
| - '%s' % (cl.GetIssue(), cl.GetIssueURL()))
|
| - change_id = cl._codereview_impl._GetChangeDetail([])['change_id']
|
| - while True:
|
| - footer_change_ids = git_footers.get_footer_change_id(message)
|
| - if footer_change_ids == [change_id]:
|
| - break
|
| - if not footer_change_ids:
|
| - message = git_footers.add_footer_change_id(message, change_id)
|
| - print('WARNING: appended missing Change-Id to issue description')
|
| - continue
|
| - # There is already a valid footer but with different or several ids.
|
| - # Doing this automatically is non-trivial as we don't want to lose
|
| - # existing other footers, yet we want to append just 1 desired
|
| - # Change-Id. Thus, just create a new footer, but let user verify the new
|
| - # description.
|
| - message = '%s\n\nChange-Id: %s' % (message, change_id)
|
| - print(
|
| - 'WARNING: issue %s has Change-Id footer(s):\n'
|
| - ' %s\n'
|
| - 'but issue has Change-Id %s, according to Gerrit.\n'
|
| - 'Please, check the proposed correction to the description, '
|
| - 'and edit it if necessary but keep the "Change-Id: %s" footer\n'
|
| - % (cl.GetIssue(), '\n '.join(footer_change_ids), change_id,
|
| - change_id))
|
| - ask_for_data('Press enter to edit now, Ctrl+C to abort')
|
| - if not options.force:
|
| - change_desc = ChangeDescription(message)
|
| - change_desc.prompt()
|
| - message = change_desc.description
|
| - if not message:
|
| - DieWithError("Description is empty. Aborting...")
|
| - # Continue the while loop.
|
| - # Sanity check of this code - we should end up with proper message footer.
|
| - assert [change_id] == git_footers.get_footer_change_id(message)
|
| - change_desc = ChangeDescription(message)
|
| - else:
|
| - change_desc = ChangeDescription(
|
| - options.message or CreateDescriptionFromLog(args))
|
| - if not options.force:
|
| - change_desc.prompt()
|
| - if not change_desc.description:
|
| - DieWithError("Description is empty. Aborting...")
|
| - message = change_desc.description
|
| - change_ids = git_footers.get_footer_change_id(message)
|
| - if len(change_ids) > 1:
|
| - DieWithError('too many Change-Id footers, at most 1 allowed.')
|
| - if not change_ids:
|
| - # Generate the Change-Id automatically.
|
| - message = git_footers.add_footer_change_id(
|
| - message, GenerateGerritChangeId(message))
|
| - change_desc.set_description(message)
|
| - change_ids = git_footers.get_footer_change_id(message)
|
| - assert len(change_ids) == 1
|
| - change_id = change_ids[0]
|
| -
|
| - remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
|
| - if remote is '.':
|
| - # If our upstream branch is local, we base our squashed commit on its
|
| - # squashed version.
|
| - upstream_branch_name = scm.GIT.ShortBranchName(upstream_branch)
|
| - # Check the squashed hash of the parent.
|
| - parent = RunGit(['config',
|
| - 'branch.%s.gerritsquashhash' % upstream_branch_name],
|
| - error_ok=True).strip()
|
| - # Verify that the upstream branch has been uploaded too, otherwise
|
| - # Gerrit will create additional CLs when uploading.
|
| - if not parent or (RunGitSilent(['rev-parse', upstream_branch + ':']) !=
|
| - RunGitSilent(['rev-parse', parent + ':'])):
|
| - # TODO(tandrii): remove "old depot_tools" part on April 12, 2016.
|
| - DieWithError(
|
| - 'Upload upstream branch %s first.\n'
|
| - 'Note: maybe you\'ve uploaded it with --no-squash or with an old\n'
|
| - ' version of depot_tools. If so, then re-upload it with:\n'
|
| - ' git cl upload --squash\n' % upstream_branch_name)
|
| - else:
|
| - parent = cl.GetCommonAncestorWithUpstream()
|
| -
|
| - tree = RunGit(['rev-parse', 'HEAD:']).strip()
|
| - ref_to_push = RunGit(['commit-tree', tree, '-p', parent,
|
| - '-m', message]).strip()
|
| - else:
|
| - change_desc = ChangeDescription(
|
| - options.message or CreateDescriptionFromLog(args))
|
| - if not change_desc.description:
|
| - DieWithError("Description is empty. Aborting...")
|
| -
|
| - if not git_footers.get_footer_change_id(change_desc.description):
|
| - DownloadGerritHook(False)
|
| - change_desc.set_description(AddChangeIdToCommitMessage(options, args))
|
| - ref_to_push = 'HEAD'
|
| - parent = '%s/%s' % (gerrit_remote, branch)
|
| - change_id = git_footers.get_footer_change_id(change_desc.description)[0]
|
| -
|
| - assert change_desc
|
| - commits = RunGitSilent(['rev-list', '%s..%s' % (parent,
|
| - ref_to_push)]).splitlines()
|
| - if len(commits) > 1:
|
| - print('WARNING: This will upload %d commits. Run the following command '
|
| - 'to see which commits will be uploaded: ' % len(commits))
|
| - print('git log %s..%s' % (parent, ref_to_push))
|
| - print('You can also use `git squash-branch` to squash these into a single '
|
| - 'commit.')
|
| - ask_for_data('About to upload; enter to confirm.')
|
| -
|
| - if options.reviewers or options.tbr_owners:
|
| - change_desc.update_reviewers(options.reviewers, options.tbr_owners, change)
|
| -
|
| - receive_options = []
|
| - cc = cl.GetCCList().split(',')
|
| - if options.cc:
|
| - cc.extend(options.cc)
|
| - cc = filter(None, cc)
|
| - if cc:
|
| - receive_options += ['--cc=' + email for email in cc]
|
| - if change_desc.get_reviewers():
|
| - receive_options.extend(
|
| - '--reviewer=' + email for email in change_desc.get_reviewers())
|
| -
|
| - git_command = ['push']
|
| - if receive_options:
|
| - git_command.append('--receive-pack=git receive-pack %s' %
|
| - ' '.join(receive_options))
|
| - git_command += [gerrit_remote, ref_to_push + ':refs/for/' + branch]
|
| - push_stdout = gclient_utils.CheckCallAndFilter(
|
| - ['git'] + git_command,
|
| - print_stdout=True,
|
| - # Flush after every line: useful for seeing progress when running as
|
| - # recipe.
|
| - filter_fn=lambda _: sys.stdout.flush())
|
| -
|
| - if options.squash:
|
| - regex = re.compile(r'remote:\s+https?://[\w\-\.\/]*/(\d+)\s.*')
|
| - change_numbers = [m.group(1)
|
| - for m in map(regex.match, push_stdout.splitlines())
|
| - if m]
|
| - if len(change_numbers) != 1:
|
| - DieWithError(
|
| - ('Created|Updated %d issues on Gerrit, but only 1 expected.\n'
|
| - 'Change-Id: %s') % (len(change_numbers), change_id))
|
| - cl.SetIssue(change_numbers[0])
|
| - RunGit(['config', 'branch.%s.gerritsquashhash' % cl.GetBranch(),
|
| - ref_to_push])
|
| - return 0
|
| -
|
| -
|
| def GetTargetRef(remote, remote_branch, target_branch, pending_prefix):
|
| """Computes the remote branch ref to use for the CL.
|
|
|
| @@ -3049,156 +3204,6 @@ def GetTargetRef(remote, remote_branch, target_branch, pending_prefix):
|
| return remote_branch
|
|
|
|
|
| -def RietveldUpload(options, args, cl, change):
|
| - """upload the patch to rietveld."""
|
| - upload_args = ['--assume_yes'] # Don't ask about untracked files.
|
| - upload_args.extend(['--server', cl.GetCodereviewServer()])
|
| - # TODO(tandrii): refactor this ugliness into _RietveldChangelistImpl.
|
| - upload_args.extend(auth.auth_config_to_command_options(
|
| - cl._codereview_impl.GetAuthConfig()))
|
| - if options.emulate_svn_auto_props:
|
| - upload_args.append('--emulate_svn_auto_props')
|
| -
|
| - change_desc = None
|
| -
|
| - if options.email is not None:
|
| - upload_args.extend(['--email', options.email])
|
| -
|
| - if cl.GetIssue():
|
| - if options.title:
|
| - upload_args.extend(['--title', options.title])
|
| - if options.message:
|
| - upload_args.extend(['--message', options.message])
|
| - upload_args.extend(['--issue', str(cl.GetIssue())])
|
| - print ("This branch is associated with issue %s. "
|
| - "Adding patch to that issue." % cl.GetIssue())
|
| - else:
|
| - if options.title:
|
| - upload_args.extend(['--title', options.title])
|
| - message = options.title or options.message or CreateDescriptionFromLog(args)
|
| - change_desc = ChangeDescription(message)
|
| - if options.reviewers or options.tbr_owners:
|
| - change_desc.update_reviewers(options.reviewers,
|
| - options.tbr_owners,
|
| - change)
|
| - if not options.force:
|
| - change_desc.prompt()
|
| -
|
| - if not change_desc.description:
|
| - print "Description is empty; aborting."
|
| - return 1
|
| -
|
| - upload_args.extend(['--message', change_desc.description])
|
| - if change_desc.get_reviewers():
|
| - upload_args.append('--reviewers=' + ','.join(change_desc.get_reviewers()))
|
| - if options.send_mail:
|
| - if not change_desc.get_reviewers():
|
| - DieWithError("Must specify reviewers to send email.")
|
| - upload_args.append('--send_mail')
|
| -
|
| - # We check this before applying rietveld.private assuming that in
|
| - # rietveld.cc only addresses which we can send private CLs to are listed
|
| - # if rietveld.private is set, and so we should ignore rietveld.cc only when
|
| - # --private is specified explicitly on the command line.
|
| - if options.private:
|
| - logging.warn('rietveld.cc is ignored since private flag is specified. '
|
| - 'You need to review and add them manually if necessary.')
|
| - cc = cl.GetCCListWithoutDefault()
|
| - else:
|
| - cc = cl.GetCCList()
|
| - cc = ','.join(filter(None, (cc, ','.join(options.cc))))
|
| - if cc:
|
| - upload_args.extend(['--cc', cc])
|
| -
|
| - if options.private or settings.GetDefaultPrivateFlag() == "True":
|
| - upload_args.append('--private')
|
| -
|
| - upload_args.extend(['--git_similarity', str(options.similarity)])
|
| - if not options.find_copies:
|
| - upload_args.extend(['--git_no_find_copies'])
|
| -
|
| - # Include the upstream repo's URL in the change -- this is useful for
|
| - # projects that have their source spread across multiple repos.
|
| - remote_url = cl.GetGitBaseUrlFromConfig()
|
| - if not remote_url:
|
| - if settings.GetIsGitSvn():
|
| - remote_url = cl.GetGitSvnRemoteUrl()
|
| - else:
|
| - if cl.GetRemoteUrl() and '/' in cl.GetUpstreamBranch():
|
| - remote_url = (cl.GetRemoteUrl() + '@'
|
| - + cl.GetUpstreamBranch().split('/')[-1])
|
| - if remote_url:
|
| - upload_args.extend(['--base_url', remote_url])
|
| - remote, remote_branch = cl.GetRemoteBranch()
|
| - target_ref = GetTargetRef(remote, remote_branch, options.target_branch,
|
| - settings.GetPendingRefPrefix())
|
| - if target_ref:
|
| - upload_args.extend(['--target_ref', target_ref])
|
| -
|
| - # Look for dependent patchsets. See crbug.com/480453 for more details.
|
| - remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
|
| - upstream_branch = ShortBranchName(upstream_branch)
|
| - if remote is '.':
|
| - # A local branch is being tracked.
|
| - local_branch = ShortBranchName(upstream_branch)
|
| - if settings.GetIsSkipDependencyUpload(local_branch):
|
| - print
|
| - print ('Skipping dependency patchset upload because git config '
|
| - 'branch.%s.skip-deps-uploads is set to True.' % local_branch)
|
| - print
|
| - else:
|
| - auth_config = auth.extract_auth_config_from_options(options)
|
| - branch_cl = Changelist(branchref=local_branch, auth_config=auth_config)
|
| - branch_cl_issue_url = branch_cl.GetIssueURL()
|
| - branch_cl_issue = branch_cl.GetIssue()
|
| - branch_cl_patchset = branch_cl.GetPatchset()
|
| - if branch_cl_issue_url and branch_cl_issue and branch_cl_patchset:
|
| - upload_args.extend(
|
| - ['--depends_on_patchset', '%s:%s' % (
|
| - branch_cl_issue, branch_cl_patchset)])
|
| - print
|
| - print ('The current branch (%s) is tracking a local branch (%s) with '
|
| - 'an associated CL.') % (cl.GetBranch(), local_branch)
|
| - print 'Adding %s/#ps%s as a dependency patchset.' % (
|
| - branch_cl_issue_url, branch_cl_patchset)
|
| - print
|
| -
|
| - project = settings.GetProject()
|
| - if project:
|
| - upload_args.extend(['--project', project])
|
| -
|
| - if options.cq_dry_run:
|
| - upload_args.extend(['--cq_dry_run'])
|
| -
|
| - try:
|
| - upload_args = ['upload'] + upload_args + args
|
| - logging.info('upload.RealMain(%s)', upload_args)
|
| - issue, patchset = upload.RealMain(upload_args)
|
| - issue = int(issue)
|
| - patchset = int(patchset)
|
| - except KeyboardInterrupt:
|
| - sys.exit(1)
|
| - except:
|
| - # If we got an exception after the user typed a description for their
|
| - # change, back up the description before re-raising.
|
| - if change_desc:
|
| - backup_path = os.path.expanduser(DESCRIPTION_BACKUP_FILE)
|
| - print '\nGot exception while uploading -- saving description to %s\n' \
|
| - % backup_path
|
| - backup_file = open(backup_path, 'w')
|
| - backup_file.write(change_desc.description)
|
| - backup_file.close()
|
| - raise
|
| -
|
| - if not cl.GetIssue():
|
| - cl.SetIssue(issue)
|
| - cl.SetPatchset(patchset)
|
| -
|
| - if options.use_commit_queue:
|
| - cl.SetFlag('commit', '1')
|
| - return 0
|
| -
|
| -
|
| def cleanup_list(l):
|
| """Fixes a list so that comma separated items are put as individual items.
|
|
|
| @@ -3349,9 +3354,7 @@ def CMDupload(parser, args):
|
| options.squash = ((settings.GetSquashGerritUploads() or options.squash) and
|
| not options.no_squash)
|
|
|
| - ret = GerritUpload(options, args, cl, change)
|
| - else:
|
| - ret = RietveldUpload(options, args, cl, change)
|
| + ret = cl.CMDUploadChange(options, args, change)
|
| if not ret:
|
| git_set_branch_value('last-upload-hash',
|
| RunGit(['rev-parse', 'HEAD']).strip())
|
|
|