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.

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

metadata/limits_test.go +4−4

@@ -70,7 +70,7 @@ func TestLoadRequestsRefusesAnOversizedFile(t *testing.T) {
70 70 t.Parallel()
71 71 g := limitsRepo(t)
72 72 huge := strings.Repeat("x", MaxFileBytes+1)
73 putIssueFile(t, g, RequestsDir+"/01M5JR2JK29KKMAA1T9MDNTPBZ/request.md",
73 putIssueFile(t, g, ChangesDir+"/01M5JR2JK29KKMAA1T9MDNTPBZ/change.md",
74 74 []byte("---\nid: 01M5JR2JK29KKMAA1T9MDNTPBZ\ntitle: huge\nauthor: keenan\nbase: main\nhead: "+
75 75 strings.Repeat("a", 40)+"\ncreated: 2026-10-27T12:00:00Z\n---\n\n"+huge))
76 76
@@ -148,14 +148,14 @@ func TestLoadRequestsReadsEveryFile(t *testing.T) {
148 148 }
149 149 files := map[string][]byte{}
150 150 for i := 0; i < n; i++ {
151 // Odd and even requests share a body, so their request.md files are the
151 // Odd and even requests share a body, so their change.md files are the
152 152 // same object under different paths.
153 153 body := requestBody(headSHA)
154 154 if i%2 == 1 {
155 155 body = requestBody(sideSHA)
156 156 }
157 files[RequestsDir+"/"+id(i)+"/request.md"] = []byte(body)
158 files[RequestsDir+"/"+id(i)+"/comments/"+id(i+n)+".md"] = []byte(
157 files[ChangesDir+"/"+id(i)+"/change.md"] = []byte(body)
158 files[ChangesDir+"/"+id(i)+"/comments/"+id(i+n)+".md"] = []byte(
159 159 "---\nauthor: keenan\ncreated: 2026-10-22T22:00:00Z\n---\n\ncomment " + string('a'+rune(i)) + "\n")
160 160 }
161 161 if _, err := git.CommitFiles(g, Ref, func(f map[string][]byte) error {