Sign in

Search issue titles and bodies, change requests and comments. Private repositories you cannot read are not included.

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.

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.

metadata/request_write.go +7

@@ -158,6 +158,10 @@ func GetRequest(g *git.Repo, id string) (*Request, error) {
158 158
159 159 // SetHead repoints a request at a new commit. The approvals stay in the tree but
160 160 // stop matching, because they name the commit they reviewed.
161 //
162 // Only an open request may move: a merged request's head is the record of what
163 // landed, and a closed one is not going to land at all. Refusing here rather than
164 // in each caller is what keeps the CLI and the browser on the same rule.
161 165 func SetRequestHead(g *git.Repo, id, head, actor string) (*Request, error) {
162 166 var out *Request
163 167 base := fmt.Sprintf("%s/%s/", RequestsDir, id)
@@ -166,6 +170,9 @@ func SetRequestHead(g *git.Repo, id, head, actor string) (*Request, error) {
166 170 if err != nil {
167 171 return err
168 172 }
173 if r.State != "open" {
174 return fmt.Errorf("requests: %s is %s, so its head cannot move", id, r.State)
175 }
169 176 r.Head = head
170 177 if err := validateRequestForWrite(r); err != nil {
171 178 return err