Connect new stacked changes implementation.

Bug: b/265929888
Change-Id: I89f669d9d0a11f09a89c378222e6780ac9fcec34
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/4189199
Reviewed-by: Josip Sokcevic <sokcevic@chromium.org>
Commit-Queue: Joanna Wang <jojwang@chromium.org>
changes/99/4189199/6
Joanna Wang 3 years ago committed by LUCI CQ
parent 00be3f079a
commit c710e2d56a

@ -4825,9 +4825,73 @@ def CMDupload(parser, args):
def UploadAllSquashed(options, orig_args):
# type: (optparse.Values, Sequence[str]) -> Tuple[Sequence[Changelist], bool]
"""Uploads the current and upstream branches (if necessary)."""
_cls, _cherry_pick_current = _UploadAllPrecheck(options, orig_args)
cls, cherry_pick_current = _UploadAllPrecheck(options, orig_args)
# Create commits.
uploads_by_cl = [] #type: Sequence[Tuple[Changelist, _NewUpload]]
if cherry_pick_current:
parent = cls[1]._GitGetBranchConfigValue(GERRIT_SQUASH_HASH_CONFIG_KEY)
new_upload = cls[0].PrepareCherryPickSquashedCommit(options, parent)
uploads_by_cl.append((cls[0], new_upload))
else:
parent = None
ordered_cls = list(reversed(cls))
for i, cl in enumerate(ordered_cls):
# If we're in the middle of the stack, set end_commit to downstream's
# direct ancestor.
if i + 1 < len(ordered_cls):
child_base_commit = ordered_cls[i + 1].GetCommonAncestorWithUpstream()
else:
child_base_commit = None
new_upload = cl.PrepareSquashedCommit(options,
parent=parent,
end_commit=child_base_commit)
uploads_by_cl.append((cl, new_upload))
parent = new_upload.commit_to_push
# Create refspec options
cl, new_upload = uploads_by_cl[-1]
refspec_opts = cl._GetRefSpecOptions(
options,
new_upload.change_desc,
multi_change_upload=len(uploads_by_cl) > 1)
refspec_suffix = ''
if refspec_opts:
refspec_suffix = '%' + ','.join(refspec_opts)
assert ' ' not in refspec_suffix, ('spaces not allowed in refspec: "%s"' %
refspec_suffix)
remote, remote_branch = cl.GetRemoteBranch()
branch = GetTargetRef(remote, remote_branch, options.target_branch)
refspec = '%s:refs/for/%s%s' % (new_upload.commit_to_push, branch,
refspec_suffix)
# Git push
git_push_metadata = {
'gerrit_host':
cl.GetGerritHost(),
'title':
options.title or '<untitled>',
'change_id':
git_footers.get_footer_change_id(new_upload.change_desc.description),
'description':
new_upload.change_desc.description,
}
push_stdout = cl._RunGitPushWithTraces(refspec, refspec_opts,
git_push_metadata)
# TODO(b/265929888): parse cls and create commits.
# Post push updates
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
]
for i, (cl, new_upload) in enumerate(uploads_by_cl):
cl.PostUploadUpdates(options, new_upload, change_numbers[i])
return 0
def _UploadAllPrecheck(options, orig_args):

@ -1514,6 +1514,159 @@ class TestGitCl(unittest.TestCase):
external_parent='newparent',
)
@mock.patch('git_cl.Changelist.GetGerritHost',
return_value='chromium-review.googlesource.com')
@mock.patch('git_cl.Changelist.GetRemoteBranch',
return_value=('origin', 'refs/remotes/origin/main'))
@mock.patch('git_cl.Changelist.PostUploadUpdates')
@mock.patch('git_cl.Changelist._RunGitPushWithTraces')
@mock.patch('git_cl._UploadAllPrecheck')
@mock.patch('git_cl.Changelist.PrepareCherryPickSquashedCommit')
def test_upload_all_squashed_cherry_pick(self, mockCherryPickCommit,
mockUploadAllPrecheck,
mockRunGitPush,
mockPostUploadUpdates, *_mocks):
# Set up
cls = [
git_cl.Changelist(branchref='refs/heads/current-branch', issue='12345'),
git_cl.Changelist(branchref='refs/heads/upstream-branch')
]
mockUploadAllPrecheck.return_value = (cls, True)
upstream_gerrit_commit = 'upstream-commit'
self.mockGit.config[
'branch.upstream-branch.gerritsquashhash'] = upstream_gerrit_commit
reviewers = []
ccs = []
commit_to_push = 'commit-to-push'
new_last_upload = 'new-last-upload'
change_desc = git_cl.ChangeDescription('stonks/nChange-Id:ec15e81197380')
new_upload = git_cl._NewUpload(reviewers, ccs, commit_to_push,
new_last_upload, upstream_gerrit_commit,
change_desc)
mockCherryPickCommit.return_value = new_upload
options = optparse.Values()
options.send_mail = options.private = False
options.squash = True
options.title = None
options.message = 'honk stonk'
options.topic = 'circus'
options.enable_auto_submit = False
options.set_bot_commit = False
options.cq_dry_run = False
options.use_commit_queue = options.cq_quick_run = False
options.hashtags = ['cow']
options.target_branch = None
orig_args = []
mockRunGitPush.return_value = (
'remote: https://chromium-review.'
'googlesource.com/c/chromium/circus/clown/+/1234 stonks')
# Call
git_cl.UploadAllSquashed(options, orig_args)
# Asserts
mockCherryPickCommit.assert_called_once_with(options,
upstream_gerrit_commit)
expected_refspec = ('commit-to-push:refs/for/refs/heads/main%notify=NONE,'
'm=honk_stonk,topic=circus,hashtag=cow')
expected_refspec_opts = [
'notify=NONE', 'm=honk_stonk', 'topic=circus', 'hashtag=cow'
]
mockRunGitPush.assert_called_once_with(expected_refspec,
expected_refspec_opts, mock.ANY)
mockPostUploadUpdates.assert_called_once_with(options, new_upload, '1234')
@mock.patch('git_cl.Changelist.GetGerritHost',
return_value='chromium-review.googlesource.com')
@mock.patch('git_cl.Changelist.GetRemoteBranch',
return_value=('origin', 'refs/remotes/origin/main'))
@mock.patch('git_cl.Changelist.GetCommonAncestorWithUpstream',
return_value='current-upstream-ancestor')
@mock.patch('git_cl.Changelist.PostUploadUpdates')
@mock.patch('git_cl.Changelist._RunGitPushWithTraces')
@mock.patch('git_cl._UploadAllPrecheck')
@mock.patch('git_cl.Changelist.PrepareSquashedCommit')
def test_upload_all_squashed(self, mockSquashedCommit, mockUploadAllPrecheck,
mockRunGitPush, mockPostUploadUpdates, *_mocks):
# Set up
cls = [
git_cl.Changelist(branchref='refs/heads/current-branch', issue='12345'),
git_cl.Changelist(branchref='refs/heads/upstream-branch')
]
mockUploadAllPrecheck.return_value = (cls, False)
reviewers = []
ccs = []
current_commit_to_push = 'commit-to-push'
current_new_last_upload = 'new-last-upload'
change_desc = git_cl.ChangeDescription('stonks/nChange-Id:ec15e81197380')
new_upload_current = git_cl._NewUpload(reviewers, ccs,
current_commit_to_push,
current_new_last_upload,
'current-upstream-ancestor',
change_desc)
upstream_desc = git_cl.ChangeDescription('kwak')
upstream_parent = 'origin-commit'
upstream_new_last_upload = 'upstrea-last-upload'
upstream_commit_to_push = 'upstream_push_commit'
new_upload_upstream = git_cl._NewUpload(reviewers, ccs,
upstream_commit_to_push,
upstream_new_last_upload,
upstream_parent, upstream_desc)
mockSquashedCommit.side_effect = [new_upload_upstream, new_upload_current]
options = optparse.Values()
options.send_mail = options.private = False
options.squash = True
options.title = None
options.message = 'honk stonk'
options.topic = 'circus'
options.enable_auto_submit = False
options.set_bot_commit = False
options.cq_dry_run = False
options.use_commit_queue = options.cq_quick_run = False
options.hashtags = ['cow']
options.target_branch = None
orig_args = []
mockRunGitPush.return_value = (
'remote: https://chromium-review.'
'googlesource.com/c/chromium/circus/clown/+/1233 kwak'
'\n'
'remote: https://chromium-review.'
'googlesource.com/c/chromium/circus/clown/+/1234 stonks')
# Call
git_cl.UploadAllSquashed(options, orig_args)
# Asserts
self.assertEqual(mockSquashedCommit.mock_calls, [
mock.call(options, parent=None, end_commit='current-upstream-ancestor'),
mock.call(options, parent=upstream_commit_to_push, end_commit=None)
])
expected_refspec = ('commit-to-push:refs/for/refs/heads/main%notify=NONE,'
'm=honk_stonk,topic=circus,hashtag=cow')
expected_refspec_opts = [
'notify=NONE', 'm=honk_stonk', 'topic=circus', 'hashtag=cow'
]
expected_refspec = ('commit-to-push:refs/for/refs/heads/main%notify=NONE,'
'topic=circus,hashtag=cow')
expected_refspec_opts = ['notify=NONE', 'topic=circus', 'hashtag=cow']
mockRunGitPush.assert_called_once_with(expected_refspec,
expected_refspec_opts, mock.ANY)
self.assertEqual(mockPostUploadUpdates.mock_calls, [
mock.call(options, new_upload_upstream, '1233'),
mock.call(options, new_upload_current, '1234')
])
@mock.patch(
'git_cl.Changelist._GerritCommitMsgHookCheck', lambda offer_removal: None)
@mock.patch('git_cl.Changelist.FetchUpstreamTuple')

Loading…
Cancel
Save