diff options
author | Bryan Jacobs <bryanrj@gmail.com> | 2013-05-06 13:36:24 -0400 |
---|---|---|
committer | Bryan Jacobs <bryanrj@gmail.com> | 2013-05-24 12:17:22 -0400 |
commit | f609f91b72c0b90026da0eefcc0f52f12840971b (patch) | |
tree | 819e244e52279d7b232df5e17727a9a828ddda66 | |
parent | 59bbb580e34bbc5dce76dacaad9ff94f21fa396f (diff) | |
download | git-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.txt | 36 | ||||
-rw-r--r-- | manifest_xml.py | 7 | ||||
-rw-r--r-- | project.py | 18 | ||||
-rw-r--r-- | subcmds/upload.py | 9 |
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 |
126 | revision attribute will use this revision. | 128 | revision attribute will use this revision. |
127 | 129 | ||
130 | Attribute `dest-branch`: Name of a Git branch (e.g. `master`). | ||
131 | Project elements not setting their own `dest-branch` will inherit | ||
132 | this value. If this value is not set, projects will use `revision` | ||
133 | by default instead. | ||
134 | |||
128 | Attribute `sync_j`: Number of parallel jobs to use when synching. | 135 | Attribute `sync_j`: Number of parallel jobs to use when synching. |
129 | 136 | ||
130 | Attribute `sync_c`: Set to true to only sync the given Git | 137 | 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 | |||
203 | been extensively tested. If not supplied the revision given by | 210 | been extensively tested. If not supplied the revision given by |
204 | the default element is used. | 211 | the default element is used. |
205 | 212 | ||
213 | Attribute `dest-branch`: Name of a Git branch (e.g. `master`). | ||
214 | When using `repo upload`, changes will be submitted for code | ||
215 | review on this branch. If unspecified both here and in the | ||
216 | default element, `revision` is used instead. | ||
217 | |||
206 | Attribute `groups`: List of groups to which this project belongs, | 218 | Attribute `groups`: List of groups to which this project belongs, |
207 | whitespace or comma separated. All projects belong to the group | 219 | whitespace 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': |
@@ -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 |