Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(459)

Unified Diff: git_cl.py

Issue 1844343002: Gerrit git cl: implement "git cl land". (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: argh, rebase Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: git_cl.py
diff --git a/git_cl.py b/git_cl.py
index f1a450973db18f773e76f21c55c722b5edcb0a63..1ffbb308cba36b84bcc5c418a3e2b40ed295913f 100755
--- a/git_cl.py
+++ b/git_cl.py
@@ -881,17 +881,17 @@ class Changelist(object):
self._remote = None
self._codereview_impl = None
+ self._codereview = None
self._load_codereview_impl(codereview, **kwargs)
+ assert self._codereview_impl
+ assert self._codereview in _CODEREVIEW_IMPLEMENTATIONS
def _load_codereview_impl(self, codereview=None, **kwargs):
if codereview:
- codereview = codereview.lower()
- if codereview == 'gerrit':
- self._codereview_impl = _GerritChangelistImpl(self, **kwargs)
- elif codereview == 'rietveld':
- self._codereview_impl = _RietveldChangelistImpl(self, **kwargs)
- else:
- assert codereview in ('rietveld', 'gerrit')
+ assert codereview in _CODEREVIEW_IMPLEMENTATIONS
+ cls = _CODEREVIEW_IMPLEMENTATIONS[codereview]
+ self._codereview = codereview
+ self._codereview_impl = cls(self, **kwargs)
return
# Automatic selection based on issue number set for a current branch.
@@ -899,10 +899,11 @@ class Changelist(object):
assert not self.issue
# Whether we find issue or not, we are doing the lookup.
self.lookedup_issue = True
- for cls in [_RietveldChangelistImpl, _GerritChangelistImpl]:
+ for codereview, cls in _CODEREVIEW_IMPLEMENTATIONS.iteritems():
setting = cls.IssueSetting(self.GetBranch())
issue = RunGit(['config', setting], error_ok=True).strip()
if issue:
+ self._codereview = codereview
self._codereview_impl = cls(self, **kwargs)
self.issue = int(issue)
return
@@ -912,6 +913,8 @@ class Changelist(object):
codereview='gerrit' if settings.GetIsGerrit() else 'rietveld',
**kwargs)
+ def IsGerrit(self):
+ return self._codereview == 'gerrit'
def GetCCList(self):
"""Return the users cc'd on this CL.
@@ -1650,11 +1653,55 @@ class _GerritChangelistImpl(_ChangelistCodereviewBase):
def CloseIssue(self):
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):
return gerrit_util.GetChangeDetail(self._GetGerritHost(), self.GetIssue(),
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):
"""Contains a parsed form of the change description."""
@@ -3110,10 +3157,14 @@ def IsSubmoduleMergeCommit(ref):
def SendUpstream(parser, args, cmd):
"""Common code for CMDland and CmdDCommit
- Squashes branch into a single commit.
- Updates changelog with metadata (e.g. pointer to review).
- Pushes/dcommits the code upstream.
- Updates review and closes.
+ In case of Gerrit, uses Gerrit REST api to "submit" the issue, which pushes
+ upstream and closes the issue automatically and atomically.
+
+ 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',
help='bypass upload presubmit hook')
@@ -3132,6 +3183,24 @@ def SendUpstream(parser, args, cmd):
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()
remote, upstream_branch = cl.FetchUpstreamTuple(cl.GetBranch())
if not settings.GetIsGitSvn() and remote == '.':
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698