summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Greenaway <dgreenaway@google.com>2022-12-09 09:38:24 +1100
committerDavid Greenaway <dgreenaway@google.com>2022-12-12 22:19:57 +0000
commitd98f3935247818eb5f5ff2f3816d67c680915161 (patch)
treee3bb555807e2d76f7ffe47ff9377278d3e7025a7
parent0324e43242ff078dfce70e80ce8e00d394f5ccdb (diff)
downloadgit-repo-d98f3935247818eb5f5ff2f3816d67c680915161.tar.gz
upload: Allow user to configure unusual commit threshold
Add a per-remote option `uploadwarningthreshold` allowing the user to override how many commits can be uploaded prior to a warning being displayed. Change-Id: Ia7e1b2c7de89a0bf9ca1c24cc83dc595b3667437 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/354375 Tested-by: David Greenaway <dgreenaway@google.com> Reviewed-by: Mike Frysinger <vapier@google.com>
-rw-r--r--docs/internal-fs-layout.md35
-rw-r--r--subcmds/upload.py88
2 files changed, 79 insertions, 44 deletions
diff --git a/docs/internal-fs-layout.md b/docs/internal-fs-layout.md
index a9bd1d26..8be61782 100644
--- a/docs/internal-fs-layout.md
+++ b/docs/internal-fs-layout.md
@@ -222,23 +222,24 @@ The `[remote]` settings are automatically populated/updated from the manifest.
222 222
223The `[branch]` settings are updated by `repo start` and `git branch`. 223The `[branch]` settings are updated by `repo start` and `git branch`.
224 224
225| Setting | Subcommands | Use/Meaning | 225| Setting | Subcommands | Use/Meaning |
226|-------------------------------|---------------|-------------| 226|---------------------------------------|---------------|-------------|
227| review.\<url\>.autocopy | upload | Automatically add to `--cc=<value>` | 227| review.\<url\>.autocopy | upload | Automatically add to `--cc=<value>` |
228| review.\<url\>.autoreviewer | upload | Automatically add to `--reviewers=<value>` | 228| review.\<url\>.autoreviewer | upload | Automatically add to `--reviewers=<value>` |
229| review.\<url\>.autoupload | upload | Automatically answer "yes" or "no" to all prompts | 229| review.\<url\>.autoupload | upload | Automatically answer "yes" or "no" to all prompts |
230| review.\<url\>.uploadhashtags | upload | Automatically add to `--hashtag=<value>` | 230| review.\<url\>.uploadhashtags | upload | Automatically add to `--hashtag=<value>` |
231| review.\<url\>.uploadlabels | upload | Automatically add to `--label=<value>` | 231| review.\<url\>.uploadlabels | upload | Automatically add to `--label=<value>` |
232| review.\<url\>.uploadnotify | upload | [Notify setting][upload-notify] to use | 232| review.\<url\>.uploadnotify | upload | [Notify setting][upload-notify] to use |
233| review.\<url\>.uploadtopic | upload | Default [topic] to use | 233| review.\<url\>.uploadtopic | upload | Default [topic] to use |
234| review.\<url\>.username | upload | Override username with `ssh://` review URIs | 234| review.\<url\>.uploadwarningthreshold | upload | Warn when attempting to upload more than this many CLs |
235| remote.\<remote\>.fetch | sync | Set of refs to fetch | 235| review.\<url\>.username | upload | Override username with `ssh://` review URIs |
236| remote.\<remote\>.projectname | \<network\> | The name of the project as it exists in Gerrit review | 236| remote.\<remote\>.fetch | sync | Set of refs to fetch |
237| remote.\<remote\>.pushurl | upload | The base URI for pushing CLs | 237| remote.\<remote\>.projectname | \<network\> | The name of the project as it exists in Gerrit review |
238| remote.\<remote\>.review | upload | The URI of the Gerrit review server | 238| remote.\<remote\>.pushurl | upload | The base URI for pushing CLs |
239| remote.\<remote\>.url | sync & upload | The URI of the git project to fetch | 239| remote.\<remote\>.review | upload | The URI of the Gerrit review server |
240| branch.\<branch\>.merge | sync & upload | The branch to merge & upload & track | 240| remote.\<remote\>.url | sync & upload | The URI of the git project to fetch |
241| branch.\<branch\>.remote | sync & upload | The remote to track | 241| branch.\<branch\>.merge | sync & upload | The branch to merge & upload & track |
242| branch.\<branch\>.remote | sync & upload | The remote to track |
242 243
243## ~/ dotconfig layout 244## ~/ dotconfig layout
244 245
diff --git a/subcmds/upload.py b/subcmds/upload.py
index 0ad3ce26..ceab6463 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -17,6 +17,7 @@ import functools
17import optparse 17import optparse
18import re 18import re
19import sys 19import sys
20from typing import List
20 21
21from command import DEFAULT_LOCAL_JOBS, InteractiveCommand 22from command import DEFAULT_LOCAL_JOBS, InteractiveCommand
22from editor import Editor 23from editor import Editor
@@ -24,21 +25,54 @@ from error import UploadError
24from git_command import GitCommand 25from git_command import GitCommand
25from git_refs import R_HEADS 26from git_refs import R_HEADS
26from hooks import RepoHook 27from hooks import RepoHook
28from project import ReviewableBranch
27 29
28 30
29UNUSUAL_COMMIT_THRESHOLD = 5 31_DEFAULT_UNUSUAL_COMMIT_THRESHOLD = 5
30 32
31 33
32def _ConfirmManyUploads(multiple_branches=False): 34def _VerifyPendingCommits(branches: List[ReviewableBranch]) -> bool:
33 if multiple_branches: 35 """Perform basic safety checks on the given set of branches.
34 print('ATTENTION: One or more branches has an unusually high number ' 36
35 'of commits.') 37 Ensures that each branch does not have a "large" number of commits
36 else: 38 and, if so, prompts the user to confirm they want to proceed with
37 print('ATTENTION: You are uploading an unusually high number of commits.') 39 the upload.
38 print('YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across ' 40
39 'branches?)') 41 Returns true if all branches pass the safety check or the user
40 answer = input("If you are sure you intend to do this, type 'yes': ").strip() 42 confirmed. Returns false if the upload should be aborted.
41 return answer == "yes" 43 """
44
45 # Determine if any branch has a suspicious number of commits.
46 many_commits = False
47 for branch in branches:
48 # Get the user's unusual threshold for the branch.
49 #
50 # Each branch may be configured to have a different threshold.
51 remote = branch.project.GetBranch(branch.name).remote
52 key = f'review.{remote.review}.uploadwarningthreshold'
53 threshold = branch.project.config.GetInt(key)
54 if threshold is None:
55 threshold = _DEFAULT_UNUSUAL_COMMIT_THRESHOLD
56
57 # If the branch has more commits than the threshold, show a warning.
58 if len(branch.commits) > threshold:
59 many_commits = True
60 break
61
62 # If any branch has many commits, prompt the user.
63 if many_commits:
64 if len(branches) > 1:
65 print('ATTENTION: One or more branches has an unusually high number '
66 'of commits.')
67 else:
68 print('ATTENTION: You are uploading an unusually high number of commits.')
69 print('YOU PROBABLY DO NOT MEAN TO DO THIS. (Did you rebase across '
70 'branches?)')
71 answer = input(
72 "If you are sure you intend to do this, type 'yes': ").strip()
73 return answer == 'yes'
74
75 return True
42 76
43 77
44def _die(fmt, *args): 78def _die(fmt, *args):
@@ -149,6 +183,13 @@ review.URL.uploadnotify:
149Control e-mail notifications when uploading. 183Control e-mail notifications when uploading.
150https://gerrit-review.googlesource.com/Documentation/user-upload.html#notify 184https://gerrit-review.googlesource.com/Documentation/user-upload.html#notify
151 185
186review.URL.uploadwarningthreshold:
187
188Repo will warn you if you are attempting to upload a large number
189of commits in one or more branches. By default, the threshold
190is five commits. This option allows you to override the warning
191threshold to a different value.
192
152# References 193# References
153 194
154Gerrit Code Review: https://www.gerritcodereview.com/ 195Gerrit Code Review: https://www.gerritcodereview.com/
@@ -261,16 +302,15 @@ Gerrit Code Review: https://www.gerritcodereview.com/
261 else: 302 else:
262 answer = sys.stdin.readline().strip().lower() 303 answer = sys.stdin.readline().strip().lower()
263 answer = answer in ('y', 'yes', '1', 'true', 't') 304 answer = answer in ('y', 'yes', '1', 'true', 't')
305 if not answer:
306 _die("upload aborted by user")
264 307
265 if not opt.yes and answer: 308 # Perform some basic safety checks prior to uploading.
266 if len(branch.commits) > UNUSUAL_COMMIT_THRESHOLD: 309 if not opt.yes and not _VerifyPendingCommits([branch]):
267 answer = _ConfirmManyUploads()
268
269 if answer:
270 self._UploadAndReport(opt, [branch], people)
271 else:
272 _die("upload aborted by user") 310 _die("upload aborted by user")
273 311
312 self._UploadAndReport(opt, [branch], people)
313
274 def _MultipleBranches(self, opt, pending, people): 314 def _MultipleBranches(self, opt, pending, people):
275 projects = {} 315 projects = {}
276 branches = {} 316 branches = {}
@@ -337,15 +377,9 @@ Gerrit Code Review: https://www.gerritcodereview.com/
337 if not todo: 377 if not todo:
338 _die("nothing uncommented for upload") 378 _die("nothing uncommented for upload")
339 379
340 if not opt.yes: 380 # Perform some basic safety checks prior to uploading.
341 many_commits = False 381 if not opt.yes and not _VerifyPendingCommits(todo):
342 for branch in todo: 382 _die("upload aborted by user")
343 if len(branch.commits) > UNUSUAL_COMMIT_THRESHOLD:
344 many_commits = True
345 break
346 if many_commits:
347 if not _ConfirmManyUploads(multiple_branches=True):
348 _die("upload aborted by user")
349 383
350 self._UploadAndReport(opt, todo, people) 384 self._UploadAndReport(opt, todo, people)
351 385