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/ssh/admin.go +7
| @@ -666,6 +666,13 @@ func (s *Server) adminACL(action string, args []string, actor string) (any, admi | |||
| 666 | 666 | if mode == "list" { | |
| 667 | 667 | return s.aclProtectedResult(m, a) | |
| 668 | 668 | } | |
| 669 | // A pattern IsProtected cannot match protects nothing, so it is refused | ||
| 670 | // here rather than stored and echoed back by `acl show` as if it worked. | ||
| 671 | if mode == "add" || mode == "set" { | ||
| 672 | if err := access.ValidateProtectedPatterns(values); err != nil { | ||
| 673 | return nil, nil, err | ||
| 674 | } | ||
| 675 | } | ||
| 669 | 676 | switch mode { | |
| 670 | 677 | case "clear": | |
| 671 | 678 | a.Protected = nil | |