Support main as default branch

R=apolito@google.com

Change-Id: Ic338c698b8eb8d2e04fc1ef23ae4b13cae08b80f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2404701
Reviewed-by: Anthony Polito <apolito@google.com>
Commit-Queue: Josip Sokcevic <sokcevic@google.com>
changes/01/2404701/4
Josip Sokcevic 5 years ago committed by LUCI CQ
parent 3eb2555a62
commit c39ab997ba

@ -37,6 +37,32 @@ def write_result(result, opt):
json_file.write(json.dumps(result)) json_file.write(json.dumps(result))
@subcommand.usage('[args ...]')
def CMDmovechanges(parser, args):
parser.add_option('-p', '--param', dest='params', action='append',
help='repeatable query parameter, format: -p key=value')
parser.add_option('--destination_branch', dest='destination_branch',
help='where to move changes to')
(opt, args) = parser.parse_args(args)
assert opt.destination_branch, "--destination_branch not defined"
host = urlparse.urlparse(opt.host).netloc
limit = 100
while True:
result = gerrit_util.QueryChanges(
host,
list(tuple(p.split('=', 1)) for p in opt.params),
limit=limit,
)
for change in result:
gerrit_util.MoveChange(host, change['id'], opt.destination_branch)
if len(result) < limit:
break
logging.info("Done")
@subcommand.usage('[args ...]') @subcommand.usage('[args ...]')
def CMDbranchinfo(parser, args): def CMDbranchinfo(parser, args):
parser.add_option('--branch', dest='branch', help='branch name') parser.add_option('--branch', dest='branch', help='branch name')

@ -706,6 +706,15 @@ def AbandonChange(host, change, msg=''):
return ReadHttpJsonResponse(conn) return ReadHttpJsonResponse(conn)
def MoveChange(host, change, destination_branch):
"""Move a Gerrit change to different destination branch."""
path = 'changes/%s/move' % change
body = {'destination_branch': destination_branch}
conn = CreateHttpConn(host, path, reqtype='POST', body=body)
return ReadHttpJsonResponse(conn)
def RestoreChange(host, change, msg=''): def RestoreChange(host, change, msg=''):
"""Restores a previously abandoned change.""" """Restores a previously abandoned change."""
path = 'changes/%s/restore' % change path = 'changes/%s/restore' % change

@ -108,6 +108,9 @@ REFS_THAT_ALIAS_TO_OTHER_REFS = {
'refs/remotes/origin/lkcr': 'refs/remotes/origin/master', 'refs/remotes/origin/lkcr': 'refs/remotes/origin/master',
} }
DEFAULT_OLD_BRANCH = 'refs/remotes/origin/master'
DEFAULT_NEW_BRANCH = 'refs/remotes/origin/main'
# Valid extensions for files we want to lint. # Valid extensions for files we want to lint.
DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)" DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
DEFAULT_LINT_IGNORE_REGEX = r"$^" DEFAULT_LINT_IGNORE_REGEX = r"$^"
@ -641,7 +644,7 @@ def _GetYapfIgnorePatterns(top_dir):
yapf is supposed to handle the ignoring of files listed in .yapfignore itself, yapf is supposed to handle the ignoring of files listed in .yapfignore itself,
but this functionality appears to break when explicitly passing files to but this functionality appears to break when explicitly passing files to
yapf for formatting. According to yapf for formatting. According to
https://github.com/google/yapf/blob/master/README.rst#excluding-files-from-formatting-yapfignore, https://github.com/google/yapf/blob/HEAD/README.rst#excluding-files-from-formatting-yapfignore,
the .yapfignore file should be in the directory that yapf is invoked from, the .yapfignore file should be in the directory that yapf is invoked from,
which we assume to be the top level directory in this case. which we assume to be the top level directory in this case.
@ -987,7 +990,7 @@ class Changelist(object):
self.more_cc.extend(more_cc) self.more_cc.extend(more_cc)
def GetBranch(self): def GetBranch(self):
"""Returns the short branch name, e.g. 'master'.""" """Returns the short branch name, e.g. 'main'."""
if not self.branch: if not self.branch:
branchref = scm.GIT.GetBranchRef(settings.GetRoot()) branchref = scm.GIT.GetBranchRef(settings.GetRoot())
if not branchref: if not branchref:
@ -997,7 +1000,7 @@ class Changelist(object):
return self.branch return self.branch
def GetBranchRef(self): def GetBranchRef(self):
"""Returns the full branch name, e.g. 'refs/heads/master'.""" """Returns the full branch name, e.g. 'refs/heads/main'."""
self.GetBranch() # Poke the lazy loader. self.GetBranch() # Poke the lazy loader.
return self.branchref return self.branchref
@ -1016,7 +1019,7 @@ class Changelist(object):
@staticmethod @staticmethod
def FetchUpstreamTuple(branch): def FetchUpstreamTuple(branch):
"""Returns a tuple containing remote and remote ref, """Returns a tuple containing remote and remote ref,
e.g. 'origin', 'refs/heads/master' e.g. 'origin', 'refs/heads/main'
""" """
remote, upstream_branch = scm.GIT.FetchUpstreamTuple( remote, upstream_branch = scm.GIT.FetchUpstreamTuple(
settings.GetRoot(), branch) settings.GetRoot(), branch)
@ -1024,7 +1027,7 @@ class Changelist(object):
DieWithError( DieWithError(
'Unable to determine default branch to diff against.\n' 'Unable to determine default branch to diff against.\n'
'Either pass complete "git diff"-style arguments, like\n' 'Either pass complete "git diff"-style arguments, like\n'
' git cl upload origin/master\n' ' git cl upload origin/main\n'
'or verify this branch is set up to track another \n' 'or verify this branch is set up to track another \n'
'(via the --track argument to "git checkout -b ...").') '(via the --track argument to "git checkout -b ...").')
@ -1226,8 +1229,8 @@ class Changelist(object):
('\nFailed to diff against upstream branch %s\n\n' ('\nFailed to diff against upstream branch %s\n\n'
'This branch probably doesn\'t exist anymore. To reset the\n' 'This branch probably doesn\'t exist anymore. To reset the\n'
'tracking branch, please run\n' 'tracking branch, please run\n'
' git branch --set-upstream-to origin/master %s\n' ' git branch --set-upstream-to origin/main %s\n'
'or replace origin/master with the relevant branch') % 'or replace origin/main with the relevant branch') %
(upstream, self.GetBranch())) (upstream, self.GetBranch()))
def UpdateDescription(self, description, force=False): def UpdateDescription(self, description, force=False):
@ -3939,10 +3942,20 @@ def GetTargetRef(remote, remote_branch, target_branch):
# Handle the refs that need to land in different refs. # Handle the refs that need to land in different refs.
remote_branch = REFS_THAT_ALIAS_TO_OTHER_REFS[remote_branch] remote_branch = REFS_THAT_ALIAS_TO_OTHER_REFS[remote_branch]
# Migration to new default branch, only if available on remote.
allow_push_on_master = bool(os.environ.get("ALLOW_PUSH_TO_MASTER", None))
if remote_branch == DEFAULT_OLD_BRANCH and not allow_push_on_master:
if RunGit(['show-branch', DEFAULT_NEW_BRANCH], error_ok=True,
stderr=subprocess2.PIPE):
# TODO(crbug.com/ID): Print location to local git migration script.
print("WARNING: Using new branch name %s instead of %s" % (
DEFAULT_NEW_BRANCH, DEFAULT_OLD_BRANCH))
remote_branch = DEFAULT_NEW_BRANCH
# Create the true path to the remote branch. # Create the true path to the remote branch.
# Does the following translation: # Does the following translation:
# * refs/remotes/origin/refs/diff/test -> refs/diff/test # * refs/remotes/origin/refs/diff/test -> refs/diff/test
# * refs/remotes/origin/master -> refs/heads/master # * refs/remotes/origin/main -> refs/heads/main
# * refs/remotes/branch-heads/test -> refs/branch-heads/test # * refs/remotes/branch-heads/test -> refs/branch-heads/test
if remote_branch.startswith('refs/remotes/%s/refs/' % remote): if remote_branch.startswith('refs/remotes/%s/refs/' % remote):
remote_branch = remote_branch.replace('refs/remotes/%s/' % remote, '') remote_branch = remote_branch.replace('refs/remotes/%s/' % remote, '')
@ -4026,7 +4039,7 @@ def CMDupload(parser, args):
'--target-branch', '--target-branch',
metavar='TARGET', metavar='TARGET',
help='Apply CL to remote ref TARGET. ' + help='Apply CL to remote ref TARGET. ' +
'Default: remote branch head, or master') 'Default: remote branch head, or main')
parser.add_option('--squash', action='store_true', parser.add_option('--squash', action='store_true',
help='Squash multiple commits into one') help='Squash multiple commits into one')
parser.add_option('--no-squash', action='store_false', dest='squash', parser.add_option('--no-squash', action='store_false', dest='squash',
@ -4382,7 +4395,7 @@ def CMDtry(parser, args):
'-r', '--revision', '-r', '--revision',
help='Revision to use for the tryjob; default: the revision will ' help='Revision to use for the tryjob; default: the revision will '
'be determined by the try recipe that builder runs, which usually ' 'be determined by the try recipe that builder runs, which usually '
'defaults to HEAD of origin/master') 'defaults to HEAD of origin/master or origin/main')
group.add_option( group.add_option(
'-c', '--clobber', action='store_true', default=False, '-c', '--clobber', action='store_true', default=False,
help='Force a clobber before building; that is don\'t do an ' help='Force a clobber before building; that is don\'t do an '

@ -647,7 +647,7 @@ class TestGitCl(unittest.TestCase):
def _gerrit_base_calls(cls, issue=None, fetched_description=None, def _gerrit_base_calls(cls, issue=None, fetched_description=None,
fetched_status=None, other_cl_owner=None, fetched_status=None, other_cl_owner=None,
custom_cl_base=None, short_hostname='chromium', custom_cl_base=None, short_hostname='chromium',
change_id=None): change_id=None, new_default=False):
calls = [] calls = []
if custom_cl_base: if custom_cl_base:
ancestor_revision = custom_cl_base ancestor_revision = custom_cl_base
@ -655,8 +655,8 @@ class TestGitCl(unittest.TestCase):
# Determine ancestor_revision to be merge base. # Determine ancestor_revision to be merge base.
ancestor_revision = 'fake_ancestor_sha' ancestor_revision = 'fake_ancestor_sha'
calls += [ calls += [
(('get_or_create_merge_base', 'master', 'refs/remotes/origin/master'), (('get_or_create_merge_base', 'master',
ancestor_revision), 'refs/remotes/origin/master'), ancestor_revision),
] ]
if issue: if issue:
@ -682,6 +682,10 @@ class TestGitCl(unittest.TestCase):
[ancestor_revision, 'HEAD']),), [ancestor_revision, 'HEAD']),),
'+dat'), '+dat'),
] ]
calls += [
((['git', 'show-branch', 'refs/remotes/origin/main'], ),
'1' if new_default else callError(1)),
]
return calls return calls
@ -693,7 +697,9 @@ class TestGitCl(unittest.TestCase):
short_hostname='chromium', short_hostname='chromium',
labels=None, change_id=None, labels=None, change_id=None,
final_description=None, gitcookies_exists=True, final_description=None, gitcookies_exists=True,
force=False, edit_description=None): force=False, edit_description=None,
new_default=False):
default_branch = 'main' if new_default else 'master';
if post_amend_description is None: if post_amend_description is None:
post_amend_description = description post_amend_description = description
cc = cc or [] cc = cc or []
@ -722,14 +728,14 @@ class TestGitCl(unittest.TestCase):
if custom_cl_base is None: if custom_cl_base is None:
calls += [ calls += [
(('get_or_create_merge_base', 'master', 'refs/remotes/origin/master'), (('get_or_create_merge_base', 'master',
'origin/master'), 'refs/remotes/origin/master'), 'origin/' + default_branch),
] ]
parent = 'origin/master' parent = 'origin/' + default_branch
else: else:
calls += [ calls += [
((['git', 'merge-base', '--is-ancestor', custom_cl_base, ((['git', 'merge-base', '--is-ancestor', custom_cl_base,
'refs/remotes/origin/master'],), 'refs/remotes/origin/' + default_branch],),
callError(1)), # Means not ancenstor. callError(1)), # Means not ancenstor.
(('ask_for_data', (('ask_for_data',
'Do you take responsibility for cleaning up potential mess ' 'Do you take responsibility for cleaning up potential mess '
@ -748,7 +754,7 @@ class TestGitCl(unittest.TestCase):
] ]
else: else:
ref_to_push = 'HEAD' ref_to_push = 'HEAD'
parent = 'origin/refs/heads/master' parent = 'origin/refs/heads/' + default_branch
calls += [ calls += [
(('SaveDescriptionBackup',), None), (('SaveDescriptionBackup',), None),
@ -834,7 +840,7 @@ class TestGitCl(unittest.TestCase):
(('time.time',), 1000,), (('time.time',), 1000,),
((['git', 'push', ((['git', 'push',
'https://%s.googlesource.com/my/repo' % short_hostname, 'https://%s.googlesource.com/my/repo' % short_hostname,
ref_to_push + ':refs/for/refs/heads/master' + ref_suffix],), ref_to_push + ':refs/for/refs/heads/' + default_branch + ref_suffix],),
(('remote:\n' (('remote:\n'
'remote: Processing changes: (\)\n' 'remote: Processing changes: (\)\n'
'remote: Processing changes: (|)\n' 'remote: Processing changes: (|)\n'
@ -848,8 +854,8 @@ class TestGitCl(unittest.TestCase):
' XXX\n' ' XXX\n'
'remote:\n' 'remote:\n'
'To https://%s.googlesource.com/my/repo\n' 'To https://%s.googlesource.com/my/repo\n'
' * [new branch] hhhh -> refs/for/refs/heads/master\n' ' * [new branch] hhhh -> refs/for/refs/heads/%s\n'
) % (short_hostname, short_hostname)),), ) % (short_hostname, short_hostname, default_branch)),),
(('time.time',), 2000,), (('time.time',), 2000,),
(('add_repeated', (('add_repeated',
'sub_commands', 'sub_commands',
@ -990,7 +996,8 @@ class TestGitCl(unittest.TestCase):
force=False, force=False,
log_description=None, log_description=None,
edit_description=None, edit_description=None,
fetched_description=None): fetched_description=None,
new_default=False):
"""Generic gerrit upload test framework.""" """Generic gerrit upload test framework."""
if squash_mode is None: if squash_mode is None:
if '--no-squash' in upload_args: if '--no-squash' in upload_args:
@ -1060,7 +1067,8 @@ class TestGitCl(unittest.TestCase):
other_cl_owner=other_cl_owner, other_cl_owner=other_cl_owner,
custom_cl_base=custom_cl_base, custom_cl_base=custom_cl_base,
short_hostname=short_hostname, short_hostname=short_hostname,
change_id=change_id) change_id=change_id,
new_default=new_default)
if fetched_status != 'ABANDONED': if fetched_status != 'ABANDONED':
mock.patch( mock.patch(
'gclient_utils.temporary_file', TemporaryFileMock()).start() 'gclient_utils.temporary_file', TemporaryFileMock()).start()
@ -1078,7 +1086,8 @@ class TestGitCl(unittest.TestCase):
final_description=final_description, final_description=final_description,
gitcookies_exists=gitcookies_exists, gitcookies_exists=gitcookies_exists,
force=force, force=force,
edit_description=edit_description) edit_description=edit_description,
new_default=new_default)
# Uncomment when debugging. # Uncomment when debugging.
# print('\n'.join(map(lambda x: '%2i: %s' % x, enumerate(self.calls)))) # print('\n'.join(map(lambda x: '%2i: %s' % x, enumerate(self.calls))))
git_cl.main(['upload'] + upload_args) git_cl.main(['upload'] + upload_args)
@ -1444,6 +1453,10 @@ class TestGitCl(unittest.TestCase):
self.assertEqual(expected, actual) self.assertEqual(expected, actual)
def test_get_hash_tags(self): def test_get_hash_tags(self):
self.calls = [
((['git', 'show-branch', 'refs/remotes/origin/main'], ),
callError(1)),
] * 9
cases = [ cases = [
('', []), ('', []),
('a', []), ('a', []),
@ -2659,6 +2672,16 @@ class TestGitCl(unittest.TestCase):
cl = git_cl.Changelist(issue=123456) cl = git_cl.Changelist(issue=123456)
self.assertEqual(cl._GerritChangeIdentifier(), '123456') self.assertEqual(cl._GerritChangeIdentifier(), '123456')
def test_gerrit_new_default(self):
self._run_gerrit_upload_test(
[],
'desc ✔\n\nBUG=\n\nChange-Id: I123456789\n',
[],
squash=False,
squash_mode='override_nosquash',
change_id='I123456789',
new_default=True)
class ChangelistTest(unittest.TestCase): class ChangelistTest(unittest.TestCase):
def setUp(self): def setUp(self):

Loading…
Cancel
Save