Send reviews to a different branch from fetch

This adds the ability to have reviews pushed to a different branch
from the one on which changes are based. This is useful for "gateway"
systems without smartsync.

Change-Id: I3a8a0fabcaf6055e62d3fb55f89c944e2f81569f
This commit is contained in:
Bryan Jacobs 2013-05-06 13:36:24 -04:00
parent 59bbb580e3
commit f609f91b72
4 changed files with 50 additions and 20 deletions

View File

@ -39,6 +39,7 @@ following DTD:
<!ELEMENT default (EMPTY)>
<!ATTLIST default remote IDREF #IMPLIED>
<!ATTLIST default revision CDATA #IMPLIED>
<!ATTLIST default dest-branch CDATA #IMPLIED>
<!ATTLIST default sync-j CDATA #IMPLIED>
<!ATTLIST default sync-c CDATA #IMPLIED>
<!ATTLIST default sync-s CDATA #IMPLIED>
@ -52,6 +53,7 @@ following DTD:
<!ATTLIST project path CDATA #IMPLIED>
<!ATTLIST project remote IDREF #IMPLIED>
<!ATTLIST project revision CDATA #IMPLIED>
<!ATTLIST project dest-branch CDATA #IMPLIED>
<!ATTLIST project groups CDATA #IMPLIED>
<!ATTLIST project sync-c CDATA #IMPLIED>
<!ATTLIST project sync-s CDATA #IMPLIED>
@ -125,6 +127,11 @@ Attribute `revision`: Name of a Git branch (e.g. `master` or
`refs/heads/master`). Project elements lacking their own
revision attribute will use this revision.
Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
Project elements not setting their own `dest-branch` will inherit
this value. If this value is not set, projects will use `revision`
by default instead.
Attribute `sync_j`: Number of parallel jobs to use when synching.
Attribute `sync_c`: Set to true to only sync the given Git
@ -203,6 +210,11 @@ Tags and/or explicit SHA-1s should work in theory, but have not
been extensively tested. If not supplied the revision given by
the default element is used.
Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
When using `repo upload`, changes will be submitted for code
review on this branch. If unspecified both here and in the
default element, `revision` is used instead.
Attribute `groups`: List of groups to which this project belongs,
whitespace or comma separated. All projects belong to the group
"all", and each project automatically belongs to a group of

View File

@ -555,6 +555,8 @@ class XmlManifest(object):
if d.revisionExpr == '':
d.revisionExpr = None
d.destBranchExpr = node.getAttribute('dest-branch') or None
sync_j = node.getAttribute('sync-j')
if sync_j == '' or sync_j is None:
d.sync_j = 1
@ -676,6 +678,8 @@ class XmlManifest(object):
raise ManifestParseError('invalid clone-depth %s in %s' %
(clone_depth, self.manifestFile))
dest_branch = node.getAttribute('dest-branch') or self._default.destBranchExpr
upstream = node.getAttribute('upstream')
groups = ''
@ -709,7 +713,8 @@ class XmlManifest(object):
sync_s = sync_s,
clone_depth = clone_depth,
upstream = upstream,
parent = parent)
parent = parent,
dest_branch = dest_branch)
for n in node.childNodes:
if n.nodeName == 'copyfile':

View File

@ -157,11 +157,12 @@ class ReviewableBranch(object):
R_HEADS + self.name,
'--')
def UploadForReview(self, people, auto_topic=False, draft=False):
def UploadForReview(self, people, auto_topic=False, draft=False, dest_branch=None):
self.project.UploadForReview(self.name,
people,
auto_topic=auto_topic,
draft=draft)
draft=draft,
dest_branch=dest_branch)
def GetPublishedRefs(self):
refs = {}
@ -497,7 +498,8 @@ class Project(object):
clone_depth = None,
upstream = None,
parent = None,
is_derived = False):
is_derived = False,
dest_branch = None):
"""Init a Project object.
Args:
@ -517,6 +519,7 @@ class Project(object):
parent: The parent Project object.
is_derived: False if the project was explicitly defined in the manifest;
True if the project is a discovered submodule.
dest_branch: The branch to which to push changes for review by default.
"""
self.manifest = manifest
self.name = name
@ -559,6 +562,7 @@ class Project(object):
self.work_git = None
self.bare_git = self._GitGetByExec(self, bare=True)
self.bare_ref = GitRefs(gitdir)
self.dest_branch = dest_branch
# This will be filled in if a project is later identified to be the
# project containing repo hooks.
@ -908,7 +912,8 @@ class Project(object):
def UploadForReview(self, branch=None,
people=([],[]),
auto_topic=False,
draft=False):
draft=False,
dest_branch=None):
"""Uploads the named branch for code review.
"""
if branch is None:
@ -922,6 +927,9 @@ class Project(object):
if not branch.remote.review:
raise GitError('remote %s has no review url' % branch.remote.name)
if dest_branch is None:
dest_branch = self.dest_branch
if dest_branch is None:
dest_branch = branch.merge
if not dest_branch.startswith(R_HEADS):
dest_branch = R_HEADS + dest_branch

View File

@ -146,6 +146,10 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
p.add_option('-d', '--draft',
action='store_true', dest='draft', default=False,
help='If specified, upload as a draft.')
p.add_option('-D', '--destination', '--dest',
type='string', action='store', dest='dest_branch',
metavar='BRANCH',
help='Submit for review on this target branch.')
# Options relating to upload hook. Note that verify and no-verify are NOT
# opposites of each other, which is why they store to different locations.
@ -185,7 +189,8 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
date = branch.date
commit_list = branch.commits
print('Upload project %s/ to remote branch %s:' % (project.relpath, project.revisionExpr))
destination = project.dest_branch or project.revisionExpr
print('Upload project %s/ to remote branch %s:' % (project.relpath, destination))
print(' branch %s (%2d commit%s, %s):' % (
name,
len(commit_list),
@ -336,7 +341,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
key = 'review.%s.uploadtopic' % branch.project.remote.review
opt.auto_topic = branch.project.config.GetBoolean(key)
branch.UploadForReview(people, auto_topic=opt.auto_topic, draft=opt.draft)
branch.UploadForReview(people, auto_topic=opt.auto_topic, draft=opt.draft, dest_branch=opt.dest_branch)
branch.uploaded = True
except UploadError as e:
branch.error = e