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/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.

Require a linked issue when a change request opens

0789f22ea633bf995417893c0052abb6a36d5520 · Keenan Nemetz · 9d ago · parent 1265ea55

Require a linked issue when a change request opens

Add a per-repository policy for teams that want every proposed update to trace back to an issue. The browser marks Closes as required, and the pre-receive hook applies the same rule to requests added through the CLI or a hand-written metadata commit. Existing requests stay editable and landable.

metadata/requests.go +35

@@ -177,6 +177,41 @@ func LoadRequestAt(g *git.Repo, commit, id string) (*Request, bool, error) {
177 177 return list[0], true, nil
178 178 }
179 179
180 // NewRequests returns the requests that were added between two commits on the
181 // metadata branch. A missing or zero old commit means the branch is being created,
182 // so every request in it is new.
183 //
184 // Repository policy applies when a request is opened, not to the requests that
185 // were already there. Comparing ids rather than paths is what keeps an edit to an
186 // existing request from being mistaken for a new one.
187 func NewRequests(g *git.Repo, oldCommit, newCommit string) ([]*Request, error) {
188 if newCommit == "" || newCommit == git.ZeroSHA {
189 return nil, nil
190 }
191 current, err := LoadRequestsAt(g, newCommit)
192 if err != nil {
193 return nil, err
194 }
195 if oldCommit == "" || oldCommit == git.ZeroSHA {
196 return current, nil
197 }
198 previous, err := LoadRequestsAt(g, oldCommit)
199 if err != nil {
200 return nil, err
201 }
202 known := make(map[string]bool, len(previous))
203 for _, req := range previous {
204 known[req.ID] = true
205 }
206 out := make([]*Request, 0, len(current))
207 for _, req := range current {
208 if !known[req.ID] {
209 out = append(out, req)
210 }
211 }
212 return out, nil
213 }
214
180 215 // RequestIDFromPath returns the request a metadata path belongs to. A changed
181 216 // file names its entity through this, so a comment or an approval updates the
182 217 // request it belongs to and nothing else.