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())
|
|