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.
Store changes under changes/<ulid>/change.md
b492b557f5cc5633b3dcb21fdbb5e2ad98d0bc16 · Keenan Nemetz · 3d ago · parent 9bce3723
Store changes under changes/<ulid>/change.md The web, the CLI, and the docs call these items changes; only the metadata tree still said requests. Rename the directory and the record file so the format and the product use one word. The tree is a contract, so this is a format change rather than a display change: the top-level layout stays closed, and a request path no longer validates. An existing repository is migrated by rewriting its vole branch, which is an audited admin force-push; the index rebuilds from the new tip and the #N aliases keep their ULIDs because the rewrite preserves commit order. Refs #202 (01M6S3JC3Y2KA6EFJK6APX7A1T).
server/events.go +3−3
| @@ -256,17 +256,17 @@ func metadataPathIDs(path string) (entityID, commentID, kind string, ok bool) { | |||
| 256 | 256 | if id.Valid(parts[1]) && id.Valid(cid) { | |
| 257 | 257 | return parts[1], cid, "issue_comment", true | |
| 258 | 258 | } | |
| 259 | case len(parts) == 3 && parts[0] == metadata.RequestsDir && parts[2] == "request.md": | ||
| 259 | case len(parts) == 3 && parts[0] == metadata.ChangesDir && parts[2] == "change.md": | ||
| 260 | 260 | if id.Valid(parts[1]) { | |
| 261 | 261 | return parts[1], "", "request", true | |
| 262 | 262 | } | |
| 263 | case len(parts) == 4 && parts[0] == metadata.RequestsDir && parts[2] == "comments" && | ||
| 263 | case len(parts) == 4 && parts[0] == metadata.ChangesDir && parts[2] == "comments" && | ||
| 264 | 264 | strings.HasSuffix(parts[3], ".md"): | |
| 265 | 265 | cid := strings.TrimSuffix(parts[3], ".md") | |
| 266 | 266 | if id.Valid(parts[1]) && id.Valid(cid) { | |
| 267 | 267 | return parts[1], cid, "request_comment", true | |
| 268 | 268 | } | |
| 269 | case len(parts) == 4 && parts[0] == metadata.RequestsDir && parts[2] == "approvals": | ||
| 269 | case len(parts) == 4 && parts[0] == metadata.ChangesDir && parts[2] == "approvals": | ||
| 270 | 270 | if id.Valid(parts[1]) { | |
| 271 | 271 | return parts[1], "", "approval", true | |
| 272 | 272 | } | |