vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
Let an author move their change request's head from the browser
53ff967be619894b62ca0ca69cd9a9f5f52bce01 · Keenan Nemetz · 13d ago · parent 8e1005eb
Let an author move their change request's head from the browser A request names the exact commit under review, so a fixup pushed after it was opened is invisible until the head moves. The only mover was `vole change update --head`, which writes the metadata branch — a write a contributor cannot make. The person who owns the branch was the one person who could not keep the request current. The request page now offers the author (or a maintainer) a branch picker that moves an open request's head to that branch's tip. It applies the same rule the new-request form does: the head must be a branch tip, and a contributor may only name a branch under their own namespace, which is what the pre-receive hook would have let them push. Approvals stay in the tree as history and stop matching, which is what a new head already means. SetRequestHead now refuses a closed or merged request, so the CLI and the browser share that rule instead of the web handler owning it alone.
server/routes.go +1
| @@ -149,6 +149,7 @@ func (s *Server) repoRoutes(mux *http.ServeMux) { | |||
| 149 | 149 | mux.HandleFunc("POST /r/{name}/requests/{id}/comments/{comment}/edit", w.EditRequestComment) | |
| 150 | 150 | mux.HandleFunc("POST /r/{name}/requests/{id}/comments/{comment}/delete", w.DeleteRequestComment) | |
| 151 | 151 | mux.HandleFunc("POST /r/{name}/requests/{id}/state", w.ChangeRequestState) | |
| 152 | mux.HandleFunc("POST /r/{name}/requests/{id}/head", w.UpdateRequestHead) | ||
| 152 | 153 | mux.HandleFunc("POST /r/{name}/ci/allow", w.AllowContributorCI) | |
| 153 | 154 | ||
| 154 | 155 | // Releases. A tag may contain "/", so the detail route takes the rest of the | |