Gerrit git cl: implement "git cl land".

R=sergiyb@chromium.org,andybons@chromium.org
BUG=579180

Review URL: https://codereview.chromium.org/1844343002

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@299589 0039d316-1c4b-4281-b951-d872f2087c98
changes/60/343160/1
tandrii@chromium.org 9 years ago
parent 512d79cd3d
commit d68b62bca0

@ -881,17 +881,17 @@ class Changelist(object):
self._remote = None self._remote = None
self._codereview_impl = None self._codereview_impl = None
self._codereview = None
self._load_codereview_impl(codereview, **kwargs) self._load_codereview_impl(codereview, **kwargs)
assert self._codereview_impl
assert self._codereview in _CODEREVIEW_IMPLEMENTATIONS
def _load_codereview_impl(self, codereview=None, **kwargs): def _load_codereview_impl(self, codereview=None, **kwargs):
if codereview: if codereview:
codereview = codereview.lower() assert codereview in _CODEREVIEW_IMPLEMENTATIONS
if codereview == 'gerrit': cls = _CODEREVIEW_IMPLEMENTATIONS[codereview]
self._codereview_impl = _GerritChangelistImpl(self, **kwargs) self._codereview = codereview
elif codereview == 'rietveld': self._codereview_impl = cls(self, **kwargs)
self._codereview_impl = _RietveldChangelistImpl(self, **kwargs)
else:
assert codereview in ('rietveld', 'gerrit')
return return
# Automatic selection based on issue number set for a current branch. # Automatic selection based on issue number set for a current branch.
@ -899,10 +899,11 @@ class Changelist(object):
assert not self.issue assert not self.issue
# Whether we find issue or not, we are doing the lookup. # Whether we find issue or not, we are doing the lookup.
self.lookedup_issue = True self.lookedup_issue = True
for cls in [_RietveldChangelistImpl, _GerritChangelistImpl]: for codereview, cls in _CODEREVIEW_IMPLEMENTATIONS.iteritems():
setting = cls.IssueSetting(self.GetBranch()) setting = cls.IssueSetting(self.GetBranch())
issue = RunGit(['config', setting], error_ok=True).strip() issue = RunGit(['config', setting], error_ok=True).strip()
if issue: if issue:
self._codereview = codereview
self._codereview_impl = cls(self, **kwargs) self._codereview_impl = cls(self, **kwargs)
self.issue = int(issue) self.issue = int(issue)
return return
@ -912,6 +913,8 @@ class Changelist(object):
codereview='gerrit' if settings.GetIsGerrit() else 'rietveld', codereview='gerrit' if settings.GetIsGerrit() else 'rietveld',
**kwargs) **kwargs)
def IsGerrit(self):
return self._codereview == 'gerrit'
def GetCCList(self): def GetCCList(self):
"""Return the users cc'd on this CL. """Return the users cc'd on this CL.
@ -1650,11 +1653,55 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
def CloseIssue(self): def CloseIssue(self):
gerrit_util.AbandonChange(self._GetGerritHost(), self.GetIssue(), msg='') gerrit_util.AbandonChange(self._GetGerritHost(), self.GetIssue(), msg='')
def SubmitIssue(self, wait_for_merge=True):
gerrit_util.SubmitChange(self._GetGerritHost(), self.GetIssue(),
wait_for_merge=wait_for_merge)
def _GetChangeDetail(self, options): def _GetChangeDetail(self, options):
return gerrit_util.GetChangeDetail(self._GetGerritHost(), self.GetIssue(), return gerrit_util.GetChangeDetail(self._GetGerritHost(), self.GetIssue(),
options) options)
def CMDLand(self, force, bypass_hooks, verbose):
if git_common.is_dirty_git_tree('land'):
return 1
differs = True
last_upload = RunGit(['config',
'branch.%s.gerritsquashhash' % self.GetBranch()],
error_ok=True).strip()
# Note: git diff outputs nothing if there is no diff.
if not last_upload or RunGit(['diff', last_upload]).strip():
print('WARNING: some changes from local branch haven\'t been uploaded')
else:
detail = self._GetChangeDetail(['CURRENT_REVISION'])
if detail['current_revision'] == last_upload:
differs = False
else:
print('WARNING: local branch contents differ from latest uploaded '
'patchset')
if differs:
if not force:
ask_for_data(
'Do you want to submit latest Gerrit patchset and bypass hooks?')
print('WARNING: bypassing hooks and submitting latest uploaded patchset')
elif not bypass_hooks:
hook_results = self.RunHook(
committing=True,
may_prompt=not force,
verbose=verbose,
change=self.GetChange(self.GetCommonAncestorWithUpstream(), None))
if not hook_results.should_continue():
return 1
self.SubmitIssue(wait_for_merge=True)
print('Issue %s has been submitted.' % self.GetIssueURL())
return 0
_CODEREVIEW_IMPLEMENTATIONS = {
'rietveld': _RietveldChangelistImpl,
'gerrit': _GerritChangelistImpl,
}
class ChangeDescription(object): class ChangeDescription(object):
"""Contains a parsed form of the change description.""" """Contains a parsed form of the change description."""
@ -3110,10 +3157,14 @@ def IsSubmoduleMergeCommit(ref):
def SendUpstream(parser, args, cmd): def SendUpstream(parser, args, cmd):
"""Common code for CMDland and CmdDCommit """Common code for CMDland and CmdDCommit
Squashes branch into a single commit. In case of Gerrit, uses Gerrit REST api to "submit" the issue, which pushes
Updates changelog with metadata (e.g. pointer to review). upstream and closes the issue automatically and atomically.
Pushes/dcommits the code upstream.
Updates review and closes. Otherwise (in case of Rietveld):
Squashes branch into a single commit.
Updates changelog with metadata (e.g. pointer to review).
Pushes/dcommits the code upstream.
Updates review and closes.
""" """
parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks', parser.add_option('--bypass-hooks', action='store_true', dest='bypass_hooks',
help='bypass upload presubmit hook') help='bypass upload presubmit hook')
@ -3132,6 +3183,24 @@ def SendUpstream(parser, args, cmd):
cl = Changelist(auth_config=auth_config) cl = Changelist(auth_config=auth_config)
# TODO(tandrii): refactor this into _RietveldChangelistImpl method.
if cl.IsGerrit():
if options.message:
# This could be implemented, but it requires sending a new patch to
# Gerrit, as Gerrit unlike Rietveld versions messages with patchsets.
# Besides, Gerrit has the ability to change the commit message on submit
# automatically, thus there is no need to support this option (so far?).
parser.error('-m MESSAGE option is not supported for Gerrit.')
if options.contributor:
parser.error(
'-c CONTRIBUTOR option is not supported for Gerrit.\n'
'Before uploading a commit to Gerrit, ensure it\'s author field is '
'the contributor\'s "name <email>". If you can\'t upload such a '
'commit for review, contact your repository admin and request'
'"Forge-Author" permission.')
return cl._codereview_impl.CMDLand(options.force, options.bypass_hooks,
options.verbose)
current = cl.GetBranch() current = cl.GetBranch()
remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch()) remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
if not settings.GetIsGitSvn() and remote == '.': if not settings.GetIsGitSvn() and remote == '.':

Loading…
Cancel
Save