diff --git a/docs/manifest-format.txt b/docs/manifest-format.txt index 59f6a2fd..dcc90d07 100644 --- a/docs/manifest-format.txt +++ b/docs/manifest-format.txt @@ -37,24 +37,26 @@ following DTD: - - - - - + + + + + + - - - - - - - + + + + + + + + @@ -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 diff --git a/manifest_xml.py b/manifest_xml.py index 16476aa5..817a1c80 100644 --- a/manifest_xml.py +++ b/manifest_xml.py @@ -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': diff --git a/project.py b/project.py index f299297d..5a7a6ca8 100644 --- a/project.py +++ b/project.py @@ -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,7 +927,10 @@ class Project(object): if not branch.remote.review: raise GitError('remote %s has no review url' % branch.remote.name) - dest_branch = branch.merge + 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 diff --git a/subcmds/upload.py b/subcmds/upload.py index 13b87784..4a22e26a 100644 --- a/subcmds/upload.py +++ b/subcmds/upload.py @@ -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