vole
Clone
Read only, no credentials:
https://rodent.software/git/vole.git
Write over SSH with a registered key:
git clone ssh://git@0.0.0.0:2222/vole.git
A free and open-source forge that lives in your Git repo.
Refuse a protected-ref pattern that can never match
93c7cae8ebb7d6d853dca476851e2bd0cbe10079 · Keenan Nemetz · 18h ago · parent 2c988ecd
Refuse a protected-ref pattern that can never match acl protect stored any string: refs/head/main read like a protected branch in acl show while the hook compared it against refs/heads/main and matched nothing, so approvals and required checks were off on the branch everything lands on. Validate the pattern in forge/access, where the rule is stored, and call it from both acl protect add|set and the repository settings form. Only the two shapes IsProtected understands are accepted, exact ref and one trailing wildcard, the ref part must be a name git could store, and a singular category is named as the typo it is.
server/web/admin_access.go +6
| @@ -95,6 +95,12 @@ func (w *Web) SaveRepositoryAccess(rw http.ResponseWriter, r *http.Request) { | |||
| 95 | 95 | checks := r.PostFormValue("checks") != "" | |
| 96 | 96 | linkedIssue := r.PostFormValue("require_linked_issue") != "" | |
| 97 | 97 | protected := splitLines(r.PostFormValue("protected")) | |
| 98 | // The same rule the CLI applies: a pattern that can never match would show | ||
| 99 | // the branch as protected in Settings and leave it open in the hook. | ||
| 100 | if err := access.ValidateProtectedPatterns(protected); err != nil { | ||
| 101 | w.accessFailure(rw, r, ctx, err.Error()) | ||
| 102 | return | ||
| 103 | } | ||
| 98 | 104 | ||
| 99 | 105 | // The rows this page rendered, and what the form said about each one. Anything | |
| 100 | 106 | // the form did not submit is not this submission's to change: an entry or a | |