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.
Test the merge result before landing it
e5478085e5b53a2892d0649d6f07c6f0a5653378 · Keenan Nemetz · 11d ago · parent db5e4382
Test the merge result before landing it A protected branch could receive a non-fast-forward landing whose tree was never built: the gate asked for checks on the request head, and the merge commit was made at landing time. A pushed merge with the right parents but extra content was accepted too. Publish the merge commit under refs/vole/candidates/, test it as the base branch, and make the gate require its results. Approvals name the head and the base branch, so a moved base retests without a new approval. A merger who clicks while that run is still going waits for it instead of clicking again. A pushed merge commit now has to carry exactly the tree a clean merge would produce. Closes: 01M61QQ56TESQ1HTMB1Z5C3733
metadata/request_find.go +7−2
| @@ -42,10 +42,15 @@ func FindRequest(g *git.Repo, id string) (*Request, error) { | |||
| 42 | 42 | ||
| 43 | 43 | // CurrentApprovals counts the approvals that still name the request's current | |
| 44 | 44 | // head and base. An approval of an older head is history, not a vote. | |
| 45 | func (r *Request) CurrentApprovals() int { | ||
| 45 | func (r *Request) CurrentApprovals() int { return r.CurrentApprovalsBy(nil) } | ||
| 46 | |||
| 47 | // CurrentApprovalsBy is CurrentApprovals with the eligibility rule the gate and the | ||
| 48 | // page use: an approval counts only while its author is still an active account | ||
| 49 | // that maintains the repository. | ||
| 50 | func (r *Request) CurrentApprovalsBy(eligible func(string) bool) int { | ||
| 46 | 51 | n := 0 | |
| 47 | 52 | for _, a := range r.Approvals { | |
| 48 | if a.Head == r.Head && a.Base == r.Base { | ||
| 53 | if a.Head == r.Head && a.Base == r.Base && (eligible == nil || eligible(a.Principal)) { | ||
| 49 | 54 | n++ | |
| 50 | 55 | } | |
| 51 | 56 | } | |