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>
diff --git a/gerrit_client.py b/gerrit_client.py
index 6b3e9de..f646c7d 100755
--- a/gerrit_client.py
+++ b/gerrit_client.py
@@ -38,6 +38,32 @@
@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 ...]')
def CMDbranchinfo(parser, args):
parser.add_option('--branch', dest='branch', help='branch name')
diff --git a/gerrit_util.py b/gerrit_util.py
index 61604a3..0077f5f 100644
--- a/gerrit_util.py
+++ b/gerrit_util.py
@@ -706,6 +706,15 @@
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=''):
"""Restores a previously abandoned change."""
path = 'changes/%s/restore' % change
diff --git a/git_cl.py b/git_cl.py
index d6ab3ef..58cb54e 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -108,6 +108,9 @@
'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.
DEFAULT_LINT_REGEX = r"(.*\.cpp|.*\.cc|.*\.h)"
DEFAULT_LINT_IGNORE_REGEX = r"$^"
@@ -641,7 +644,7 @@
yapf is supposed to handle the ignoring of files listed in .yapfignore itself,
but this functionality appears to break when explicitly passing files 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,
which we assume to be the top level directory in this case.
@@ -987,7 +990,7 @@
self.more_cc.extend(more_cc)
def GetBranch(self):
- """Returns the short branch name, e.g. 'master'."""
+ """Returns the short branch name, e.g. 'main'."""
if not self.branch:
branchref = scm.GIT.GetBranchRef(settings.GetRoot())
if not branchref:
@@ -997,7 +1000,7 @@
return self.branch
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.
return self.branchref
@@ -1016,7 +1019,7 @@
@staticmethod
def FetchUpstreamTuple(branch):
"""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(
settings.GetRoot(), branch)
@@ -1024,7 +1027,7 @@
DieWithError(
'Unable to determine default branch to diff against.\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'
'(via the --track argument to "git checkout -b ...").')
@@ -1226,8 +1229,8 @@
('\nFailed to diff against upstream branch %s\n\n'
'This branch probably doesn\'t exist anymore. To reset the\n'
'tracking branch, please run\n'
- ' git branch --set-upstream-to origin/master %s\n'
- 'or replace origin/master with the relevant branch') %
+ ' git branch --set-upstream-to origin/main %s\n'
+ 'or replace origin/main with the relevant branch') %
(upstream, self.GetBranch()))
def UpdateDescription(self, description, force=False):
@@ -3939,10 +3942,20 @@
# Handle the refs that need to land in different refs.
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.
# Does the following translation:
# * 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
if remote_branch.startswith('refs/remotes/%s/refs/' % remote):
remote_branch = remote_branch.replace('refs/remotes/%s/' % remote, '')
@@ -4026,7 +4039,7 @@
'--target-branch',
metavar='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',
help='Squash multiple commits into one')
parser.add_option('--no-squash', action='store_false', dest='squash',
@@ -4382,7 +4395,7 @@
'-r', '--revision',
help='Revision to use for the tryjob; default: the revision will '
'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(
'-c', '--clobber', action='store_true', default=False,
help='Force a clobber before building; that is don\'t do an '
diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py
index 45f34c8..cf788f7 100755
--- a/tests/git_cl_test.py
+++ b/tests/git_cl_test.py
@@ -647,7 +647,7 @@
def _gerrit_base_calls(cls, issue=None, fetched_description=None,
fetched_status=None, other_cl_owner=None,
custom_cl_base=None, short_hostname='chromium',
- change_id=None):
+ change_id=None, new_default=False):
calls = []
if custom_cl_base:
ancestor_revision = custom_cl_base
@@ -655,8 +655,8 @@
# Determine ancestor_revision to be merge base.
ancestor_revision = 'fake_ancestor_sha'
calls += [
- (('get_or_create_merge_base', 'master', 'refs/remotes/origin/master'),
- ancestor_revision),
+ (('get_or_create_merge_base', 'master',
+ 'refs/remotes/origin/master'), ancestor_revision),
]
if issue:
@@ -682,6 +682,10 @@
[ancestor_revision, 'HEAD']),),
'+dat'),
]
+ calls += [
+ ((['git', 'show-branch', 'refs/remotes/origin/main'], ),
+ '1' if new_default else callError(1)),
+ ]
return calls
@@ -693,7 +697,9 @@
short_hostname='chromium',
labels=None, change_id=None,
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:
post_amend_description = description
cc = cc or []
@@ -722,14 +728,14 @@
if custom_cl_base is None:
calls += [
- (('get_or_create_merge_base', 'master', 'refs/remotes/origin/master'),
- 'origin/master'),
+ (('get_or_create_merge_base', 'master',
+ 'refs/remotes/origin/master'), 'origin/' + default_branch),
]
- parent = 'origin/master'
+ parent = 'origin/' + default_branch
else:
calls += [
((['git', 'merge-base', '--is-ancestor', custom_cl_base,
- 'refs/remotes/origin/master'],),
+ 'refs/remotes/origin/' + default_branch],),
callError(1)), # Means not ancenstor.
(('ask_for_data',
'Do you take responsibility for cleaning up potential mess '
@@ -748,7 +754,7 @@
]
else:
ref_to_push = 'HEAD'
- parent = 'origin/refs/heads/master'
+ parent = 'origin/refs/heads/' + default_branch
calls += [
(('SaveDescriptionBackup',), None),
@@ -834,7 +840,7 @@
(('time.time',), 1000,),
((['git', 'push',
'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: Processing changes: (\)\n'
'remote: Processing changes: (|)\n'
@@ -848,8 +854,8 @@
' XXX\n'
'remote:\n'
'To https://%s.googlesource.com/my/repo\n'
- ' * [new branch] hhhh -> refs/for/refs/heads/master\n'
- ) % (short_hostname, short_hostname)),),
+ ' * [new branch] hhhh -> refs/for/refs/heads/%s\n'
+ ) % (short_hostname, short_hostname, default_branch)),),
(('time.time',), 2000,),
(('add_repeated',
'sub_commands',
@@ -990,7 +996,8 @@
force=False,
log_description=None,
edit_description=None,
- fetched_description=None):
+ fetched_description=None,
+ new_default=False):
"""Generic gerrit upload test framework."""
if squash_mode is None:
if '--no-squash' in upload_args:
@@ -1060,7 +1067,8 @@
other_cl_owner=other_cl_owner,
custom_cl_base=custom_cl_base,
short_hostname=short_hostname,
- change_id=change_id)
+ change_id=change_id,
+ new_default=new_default)
if fetched_status != 'ABANDONED':
mock.patch(
'gclient_utils.temporary_file', TemporaryFileMock()).start()
@@ -1078,7 +1086,8 @@
final_description=final_description,
gitcookies_exists=gitcookies_exists,
force=force,
- edit_description=edit_description)
+ edit_description=edit_description,
+ new_default=new_default)
# Uncomment when debugging.
# print('\n'.join(map(lambda x: '%2i: %s' % x, enumerate(self.calls))))
git_cl.main(['upload'] + upload_args)
@@ -1444,6 +1453,10 @@
self.assertEqual(expected, actual)
def test_get_hash_tags(self):
+ self.calls = [
+ ((['git', 'show-branch', 'refs/remotes/origin/main'], ),
+ callError(1)),
+ ] * 9
cases = [
('', []),
('a', []),
@@ -2659,6 +2672,16 @@
cl = git_cl.Changelist(issue=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):
def setUp(self):