summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBryan Jacobs <bryanrj@gmail.com>2013-05-06 13:36:24 -0400
committerBryan Jacobs <bryanrj@gmail.com>2013-05-24 12:17:22 -0400
commitf609f91b72c0b90026da0eefcc0f52f12840971b (patch)
tree819e244e52279d7b232df5e17727a9a828ddda66
parent59bbb580e34bbc5dce76dacaad9ff94f21fa396f (diff)
downloadgit-repo-f609f91b72c0b90026da0eefcc0f52f12840971b.tar.gz
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
-rw-r--r--docs/manifest-format.txt36
-rw-r--r--manifest_xml.py7
-rw-r--r--project.py18
-rw-r--r--subcmds/upload.py9
4 files changed, 50 insertions, 20 deletions
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:
37 <!ATTLIST remote review CDATA #IMPLIED> 37 <!ATTLIST remote review CDATA #IMPLIED>
38 38
39 <!ELEMENT default (EMPTY)> 39 <!ELEMENT default (EMPTY)>
40 <!ATTLIST default remote IDREF #IMPLIED> 40 <!ATTLIST default remote IDREF #IMPLIED>
41 <!ATTLIST default revision CDATA #IMPLIED> 41 <!ATTLIST default revision CDATA #IMPLIED>
42 <!ATTLIST default sync-j CDATA #IMPLIED> 42 <!ATTLIST default dest-branch CDATA #IMPLIED>
43 <!ATTLIST default sync-c CDATA #IMPLIED> 43 <!ATTLIST default sync-j CDATA #IMPLIED>
44 <!ATTLIST default sync-s CDATA #IMPLIED> 44 <!ATTLIST default sync-c CDATA #IMPLIED>
45 <!ATTLIST default sync-s CDATA #IMPLIED>
45 46
46 <!ELEMENT manifest-server (EMPTY)> 47 <!ELEMENT manifest-server (EMPTY)>
47 <!ATTLIST url CDATA #REQUIRED> 48 <!ATTLIST url CDATA #REQUIRED>
48 49
49 <!ELEMENT project (annotation?, 50 <!ELEMENT project (annotation?,
50 project*)> 51 project*)>
51 <!ATTLIST project name CDATA #REQUIRED> 52 <!ATTLIST project name CDATA #REQUIRED>
52 <!ATTLIST project path CDATA #IMPLIED> 53 <!ATTLIST project path CDATA #IMPLIED>
53 <!ATTLIST project remote IDREF #IMPLIED> 54 <!ATTLIST project remote IDREF #IMPLIED>
54 <!ATTLIST project revision CDATA #IMPLIED> 55 <!ATTLIST project revision CDATA #IMPLIED>
55 <!ATTLIST project groups CDATA #IMPLIED> 56 <!ATTLIST project dest-branch CDATA #IMPLIED>
56 <!ATTLIST project sync-c CDATA #IMPLIED> 57 <!ATTLIST project groups CDATA #IMPLIED>
57 <!ATTLIST project sync-s CDATA #IMPLIED> 58 <!ATTLIST project sync-c CDATA #IMPLIED>
59 <!ATTLIST project sync-s CDATA #IMPLIED>
58 <!ATTLIST project upstream CDATA #IMPLIED> 60 <!ATTLIST project upstream CDATA #IMPLIED>
59 <!ATTLIST project clone-depth CDATA #IMPLIED> 61 <!ATTLIST project clone-depth CDATA #IMPLIED>
60 <!ATTLIST project force-path CDATA #IMPLIED> 62 <!ATTLIST project force-path CDATA #IMPLIED>
@@ -125,6 +127,11 @@ Attribute `revision`: Name of a Git branch (e.g. `master` or
125`refs/heads/master`). Project elements lacking their own 127`refs/heads/master`). Project elements lacking their own
126revision attribute will use this revision. 128revision attribute will use this revision.
127 129
130Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
131Project elements not setting their own `dest-branch` will inherit
132this value. If this value is not set, projects will use `revision`
133by default instead.
134
128Attribute `sync_j`: Number of parallel jobs to use when synching. 135Attribute `sync_j`: Number of parallel jobs to use when synching.
129 136
130Attribute `sync_c`: Set to true to only sync the given Git 137Attribute `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
203been extensively tested. If not supplied the revision given by 210been extensively tested. If not supplied the revision given by
204the default element is used. 211the default element is used.
205 212
213Attribute `dest-branch`: Name of a Git branch (e.g. `master`).
214When using `repo upload`, changes will be submitted for code
215review on this branch. If unspecified both here and in the
216default element, `revision` is used instead.
217
206Attribute `groups`: List of groups to which this project belongs, 218Attribute `groups`: List of groups to which this project belongs,
207whitespace or comma separated. All projects belong to the group 219whitespace or comma separated. All projects belong to the group
208"all", and each project automatically belongs to a group of 220"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):
555 if d.revisionExpr == '': 555 if d.revisionExpr == '':
556 d.revisionExpr = None 556 d.revisionExpr = None
557 557
558 d.destBranchExpr = node.getAttribute('dest-branch') or None
559
558 sync_j = node.getAttribute('sync-j') 560 sync_j = node.getAttribute('sync-j')
559 if sync_j == '' or sync_j is None: 561 if sync_j == '' or sync_j is None:
560 d.sync_j = 1 562 d.sync_j = 1
@@ -676,6 +678,8 @@ class XmlManifest(object):
676 raise ManifestParseError('invalid clone-depth %s in %s' % 678 raise ManifestParseError('invalid clone-depth %s in %s' %
677 (clone_depth, self.manifestFile)) 679 (clone_depth, self.manifestFile))
678 680
681 dest_branch = node.getAttribute('dest-branch') or self._default.destBranchExpr
682
679 upstream = node.getAttribute('upstream') 683 upstream = node.getAttribute('upstream')
680 684
681 groups = '' 685 groups = ''
@@ -709,7 +713,8 @@ class XmlManifest(object):
709 sync_s = sync_s, 713 sync_s = sync_s,
710 clone_depth = clone_depth, 714 clone_depth = clone_depth,
711 upstream = upstream, 715 upstream = upstream,
712 parent = parent) 716 parent = parent,
717 dest_branch = dest_branch)
713 718
714 for n in node.childNodes: 719 for n in node.childNodes:
715 if n.nodeName == 'copyfile': 720 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):
157 R_HEADS + self.name, 157 R_HEADS + self.name,
158 '--') 158 '--')
159 159
160 def UploadForReview(self, people, auto_topic=False, draft=False): 160 def UploadForReview(self, people, auto_topic=False, draft=False, dest_branch=None):
161 self.project.UploadForReview(self.name, 161 self.project.UploadForReview(self.name,
162 people, 162 people,
163 auto_topic=auto_topic, 163 auto_topic=auto_topic,
164 draft=draft) 164 draft=draft,
165 dest_branch=dest_branch)
165 166
166 def GetPublishedRefs(self): 167 def GetPublishedRefs(self):
167 refs = {} 168 refs = {}
@@ -497,7 +498,8 @@ class Project(object):
497 clone_depth = None, 498 clone_depth = None,
498 upstream = None, 499 upstream = None,
499 parent = None, 500 parent = None,
500 is_derived = False): 501 is_derived = False,
502 dest_branch = None):
501 """Init a Project object. 503 """Init a Project object.
502 504
503 Args: 505 Args:
@@ -517,6 +519,7 @@ class Project(object):
517 parent: The parent Project object. 519 parent: The parent Project object.
518 is_derived: False if the project was explicitly defined in the manifest; 520 is_derived: False if the project was explicitly defined in the manifest;
519 True if the project is a discovered submodule. 521 True if the project is a discovered submodule.
522 dest_branch: The branch to which to push changes for review by default.
520 """ 523 """
521 self.manifest = manifest 524 self.manifest = manifest
522 self.name = name 525 self.name = name
@@ -559,6 +562,7 @@ class Project(object):
559 self.work_git = None 562 self.work_git = None
560 self.bare_git = self._GitGetByExec(self, bare=True) 563 self.bare_git = self._GitGetByExec(self, bare=True)
561 self.bare_ref = GitRefs(gitdir) 564 self.bare_ref = GitRefs(gitdir)
565 self.dest_branch = dest_branch
562 566
563 # This will be filled in if a project is later identified to be the 567 # This will be filled in if a project is later identified to be the
564 # project containing repo hooks. 568 # project containing repo hooks.
@@ -908,7 +912,8 @@ class Project(object):
908 def UploadForReview(self, branch=None, 912 def UploadForReview(self, branch=None,
909 people=([],[]), 913 people=([],[]),
910 auto_topic=False, 914 auto_topic=False,
911 draft=False): 915 draft=False,
916 dest_branch=None):
912 """Uploads the named branch for code review. 917 """Uploads the named branch for code review.
913 """ 918 """
914 if branch is None: 919 if branch is None:
@@ -922,7 +927,10 @@ class Project(object):
922 if not branch.remote.review: 927 if not branch.remote.review:
923 raise GitError('remote %s has no review url' % branch.remote.name) 928 raise GitError('remote %s has no review url' % branch.remote.name)
924 929
925 dest_branch = branch.merge 930 if dest_branch is None:
931 dest_branch = self.dest_branch
932 if dest_branch is None:
933 dest_branch = branch.merge
926 if not dest_branch.startswith(R_HEADS): 934 if not dest_branch.startswith(R_HEADS):
927 dest_branch = R_HEADS + dest_branch 935 dest_branch = R_HEADS + dest_branch
928 936
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/
146 p.add_option('-d', '--draft', 146 p.add_option('-d', '--draft',
147 action='store_true', dest='draft', default=False, 147 action='store_true', dest='draft', default=False,
148 help='If specified, upload as a draft.') 148 help='If specified, upload as a draft.')
149 p.add_option('-D', '--destination', '--dest',
150 type='string', action='store', dest='dest_branch',
151 metavar='BRANCH',
152 help='Submit for review on this target branch.')
149 153
150 # Options relating to upload hook. Note that verify and no-verify are NOT 154 # Options relating to upload hook. Note that verify and no-verify are NOT
151 # opposites of each other, which is why they store to different locations. 155 # 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/
185 date = branch.date 189 date = branch.date
186 commit_list = branch.commits 190 commit_list = branch.commits
187 191
188 print('Upload project %s/ to remote branch %s:' % (project.relpath, project.revisionExpr)) 192 destination = project.dest_branch or project.revisionExpr
193 print('Upload project %s/ to remote branch %s:' % (project.relpath, destination))
189 print(' branch %s (%2d commit%s, %s):' % ( 194 print(' branch %s (%2d commit%s, %s):' % (
190 name, 195 name,
191 len(commit_list), 196 len(commit_list),
@@ -336,7 +341,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
336 key = 'review.%s.uploadtopic' % branch.project.remote.review 341 key = 'review.%s.uploadtopic' % branch.project.remote.review
337 opt.auto_topic = branch.project.config.GetBoolean(key) 342 opt.auto_topic = branch.project.config.GetBoolean(key)
338 343
339 branch.UploadForReview(people, auto_topic=opt.auto_topic, draft=opt.draft) 344 branch.UploadForReview(people, auto_topic=opt.auto_topic, draft=opt.draft, dest_branch=opt.dest_branch)
340 branch.uploaded = True 345 branch.uploaded = True
341 except UploadError as e: 346 except UploadError as e:
342 branch.error = e 347 branch.error = e