summaryrefslogtreecommitdiffstats
path: root/subcmds/upload.py
diff options
context:
space:
mode:
Diffstat (limited to 'subcmds/upload.py')
-rw-r--r--subcmds/upload.py96
1 files changed, 83 insertions, 13 deletions
diff --git a/subcmds/upload.py b/subcmds/upload.py
index 20822096..c9312973 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -19,7 +19,8 @@ import sys
19 19
20from command import InteractiveCommand 20from command import InteractiveCommand
21from editor import Editor 21from editor import Editor
22from error import UploadError 22from error import HookError, UploadError
23from project import RepoHook
23 24
24UNUSUAL_COMMIT_THRESHOLD = 5 25UNUSUAL_COMMIT_THRESHOLD = 5
25 26
@@ -72,7 +73,7 @@ Configuration
72 73
73review.URL.autoupload: 74review.URL.autoupload:
74 75
75To disable the "Upload ... (y/n)?" prompt, you can set a per-project 76To disable the "Upload ... (y/N)?" prompt, you can set a per-project
76or global Git configuration option. If review.URL.autoupload is set 77or global Git configuration option. If review.URL.autoupload is set
77to "true" then repo will assume you always answer "y" at the prompt, 78to "true" then repo will assume you always answer "y" at the prompt,
78and will not prompt you further. If it is set to "false" then repo 79and will not prompt you further. If it is set to "false" then repo
@@ -102,6 +103,14 @@ or in the .git/config within the project. For example:
102 autoupload = true 103 autoupload = true
103 autocopy = johndoe@company.com,my-team-alias@company.com 104 autocopy = johndoe@company.com,my-team-alias@company.com
104 105
106review.URL.uploadtopic:
107
108To add a topic branch whenever uploading a commit, you can set a
109per-project or global Git option to do so. If review.URL.uploadtopic
110is set to "true" then repo will assume you always want the equivalent
111of the -t option to the repo command. If unset or set to "false" then
112repo will make use of only the command line option.
113
105References 114References
106---------- 115----------
107 116
@@ -119,6 +128,38 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
119 p.add_option('--cc', 128 p.add_option('--cc',
120 type='string', action='append', dest='cc', 129 type='string', action='append', dest='cc',
121 help='Also send email to these email addresses.') 130 help='Also send email to these email addresses.')
131 p.add_option('--br',
132 type='string', action='store', dest='branch',
133 help='Branch to upload.')
134 p.add_option('--cbr', '--current-branch',
135 dest='current_branch', action='store_true',
136 help='Upload current git branch.')
137 p.add_option('-d', '--draft',
138 action='store_true', dest='draft', default=False,
139 help='If specified, upload as a draft.')
140
141 # Options relating to upload hook. Note that verify and no-verify are NOT
142 # opposites of each other, which is why they store to different locations.
143 # We are using them to match 'git commit' syntax.
144 #
145 # Combinations:
146 # - no-verify=False, verify=False (DEFAULT):
147 # If stdout is a tty, can prompt about running upload hooks if needed.
148 # If user denies running hooks, the upload is cancelled. If stdout is
149 # not a tty and we would need to prompt about upload hooks, upload is
150 # cancelled.
151 # - no-verify=False, verify=True:
152 # Always run upload hooks with no prompt.
153 # - no-verify=True, verify=False:
154 # Never run upload hooks, but upload anyway (AKA bypass hooks).
155 # - no-verify=True, verify=True:
156 # Invalid
157 p.add_option('--no-verify',
158 dest='bypass_hooks', action='store_true',
159 help='Do not run the upload hook.')
160 p.add_option('--verify',
161 dest='allow_all_hooks', action='store_true',
162 help='Run the upload hook without prompting.')
122 163
123 def _SingleBranch(self, opt, branch, people): 164 def _SingleBranch(self, opt, branch, people):
124 project = branch.project 165 project = branch.project
@@ -135,7 +176,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
135 date = branch.date 176 date = branch.date
136 list = branch.commits 177 list = branch.commits
137 178
138 print 'Upload project %s/:' % project.relpath 179 print 'Upload project %s/ to remote branch %s:' % (project.relpath, project.revisionExpr)
139 print ' branch %s (%2d commit%s, %s):' % ( 180 print ' branch %s (%2d commit%s, %s):' % (
140 name, 181 name,
141 len(list), 182 len(list),
@@ -144,7 +185,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
144 for commit in list: 185 for commit in list:
145 print ' %s' % commit 186 print ' %s' % commit
146 187
147 sys.stdout.write('to %s (y/n)? ' % remote.review) 188 sys.stdout.write('to %s (y/N)? ' % remote.review)
148 answer = sys.stdin.readline().strip() 189 answer = sys.stdin.readline().strip()
149 answer = answer in ('y', 'Y', 'yes', '1', 'true', 't') 190 answer = answer in ('y', 'Y', 'yes', '1', 'true', 't')
150 191
@@ -175,11 +216,12 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
175 216
176 if b: 217 if b:
177 script.append('#') 218 script.append('#')
178 script.append('# branch %s (%2d commit%s, %s):' % ( 219 script.append('# branch %s (%2d commit%s, %s) to remote branch %s:' % (
179 name, 220 name,
180 len(list), 221 len(list),
181 len(list) != 1 and 's' or '', 222 len(list) != 1 and 's' or '',
182 date)) 223 date,
224 project.revisionExpr))
183 for commit in list: 225 for commit in list:
184 script.append('# %s' % commit) 226 script.append('# %s' % commit)
185 b[name] = branch 227 b[name] = branch
@@ -188,6 +230,11 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
188 branches[project.name] = b 230 branches[project.name] = b
189 script.append('') 231 script.append('')
190 232
233 script = [ x.encode('utf-8')
234 if issubclass(type(x), unicode)
235 else x
236 for x in script ]
237
191 script = Editor.EditString("\n".join(script)).split("\n") 238 script = Editor.EditString("\n".join(script)).split("\n")
192 239
193 project_re = re.compile(r'^#?\s*project\s*([^\s]+)/:$') 240 project_re = re.compile(r'^#?\s*project\s*([^\s]+)/:$')
@@ -267,7 +314,7 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
267 314
268 # if they want to auto upload, let's not ask because it could be automated 315 # if they want to auto upload, let's not ask because it could be automated
269 if answer is None: 316 if answer is None:
270 sys.stdout.write('Uncommitted changes in ' + branch.project.name + ' (did you forget to amend?). Continue uploading? (y/n) ') 317 sys.stdout.write('Uncommitted changes in ' + branch.project.name + ' (did you forget to amend?). Continue uploading? (y/N) ')
271 a = sys.stdin.readline().strip().lower() 318 a = sys.stdin.readline().strip().lower()
272 if a not in ('y', 'yes', 't', 'true', 'on'): 319 if a not in ('y', 'yes', 't', 'true', 'on'):
273 print >>sys.stderr, "skipping upload" 320 print >>sys.stderr, "skipping upload"
@@ -275,7 +322,12 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
275 branch.error = 'User aborted' 322 branch.error = 'User aborted'
276 continue 323 continue
277 324
278 branch.UploadForReview(people, auto_topic=opt.auto_topic) 325 # Check if topic branches should be sent to the server during upload
326 if opt.auto_topic is not True:
327 key = 'review.%s.uploadtopic' % branch.project.remote.review
328 opt.auto_topic = branch.project.config.GetBoolean(key)
329
330 branch.UploadForReview(people, auto_topic=opt.auto_topic, draft=opt.draft)
279 branch.uploaded = True 331 branch.uploaded = True
280 except UploadError, e: 332 except UploadError, e:
281 branch.error = e 333 branch.error = e
@@ -312,6 +364,29 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
312 pending = [] 364 pending = []
313 reviewers = [] 365 reviewers = []
314 cc = [] 366 cc = []
367 branch = None
368
369 if opt.branch:
370 branch = opt.branch
371
372 for project in project_list:
373 if opt.current_branch:
374 cbr = project.CurrentBranch
375 avail = [project.GetUploadableBranch(cbr)] if cbr else None
376 else:
377 avail = project.GetUploadableBranches(branch)
378 if avail:
379 pending.append((project, avail))
380
381 if pending and (not opt.bypass_hooks):
382 hook = RepoHook('pre-upload', self.manifest.repo_hooks_project,
383 self.manifest.topdir, abort_if_user_denies=True)
384 pending_proj_names = [project.name for (project, avail) in pending]
385 try:
386 hook.Run(opt.allow_all_hooks, project_list=pending_proj_names)
387 except HookError, e:
388 print >>sys.stderr, "ERROR: %s" % str(e)
389 return
315 390
316 if opt.reviewers: 391 if opt.reviewers:
317 reviewers = _SplitEmails(opt.reviewers) 392 reviewers = _SplitEmails(opt.reviewers)
@@ -319,11 +394,6 @@ Gerrit Code Review: http://code.google.com/p/gerrit/
319 cc = _SplitEmails(opt.cc) 394 cc = _SplitEmails(opt.cc)
320 people = (reviewers,cc) 395 people = (reviewers,cc)
321 396
322 for project in project_list:
323 avail = project.GetUploadableBranches()
324 if avail:
325 pending.append((project, avail))
326
327 if not pending: 397 if not pending:
328 print >>sys.stdout, "no branches ready for upload" 398 print >>sys.stdout, "no branches ready for upload"
329 elif len(pending) == 1 and len(pending[0][1]) == 1: 399 elif len(pending) == 1 and len(pending[0][1]) == 1: