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/issues_changes_test.go +7−7
| @@ -1340,7 +1340,7 @@ func TestLandingRedirectsToTheRequestPage(t *testing.T) { | |||
| 1340 | 1340 | } | |
| 1341 | 1341 | meta := f.newMetaRepo(t) | |
| 1342 | 1342 | if err := meta.apply(map[string]string{ | |
| 1343 | "requests/" + reqID + "/request.md": requestMeta("main", head, "wilbur"), | ||
| 1343 | "changes/" + reqID + "/change.md": requestMeta("main", head, "wilbur"), | ||
| 1344 | 1344 | }, "request"); err != nil { | |
| 1345 | 1345 | t.Fatalf("request: %v", err) | |
| 1346 | 1346 | } | |
| @@ -1525,12 +1525,12 @@ func TestChangeListShowsOneStatus(t *testing.T) { | |||
| 1525 | 1525 | const followingID = "01M5JR2JK29KKMAA1T9MDNTR06" | |
| 1526 | 1526 | meta := f.newMetaRepo(t) | |
| 1527 | 1527 | if err := meta.apply(map[string]string{ | |
| 1528 | "requests/" + reviewID + "/request.md": requestFileTitled("Needs a review", "main", firstHead, "keenan", "body\n"), | ||
| 1529 | "requests/" + approvedID + "/request.md": requestFileTitled("Approved change", "main", secondHead, "wilbur", "body\n"), | ||
| 1530 | "requests/" + approvedID + "/approvals/" + f.accountName("keenan") + ".md": approvalFile("main", secondHead), | ||
| 1531 | "requests/" + mergedID + "/request.md": requestFileMerged("Landed change", "main", secondHead, "wilbur", "keenan", nil), | ||
| 1532 | "requests/" + closedID + "/request.md": requestFileState("Dropped change", "main", firstHead, "wilbur", "closed", "body\n"), | ||
| 1533 | "requests/" + followingID + "/request.md": requestFileFollowing("Follows a branch", "main", firstHead, "feature-one", "keenan", "body\n"), | ||
| 1528 | "changes/" + reviewID + "/change.md": requestFileTitled("Needs a review", "main", firstHead, "keenan", "body\n"), | ||
| 1529 | "changes/" + approvedID + "/change.md": requestFileTitled("Approved change", "main", secondHead, "wilbur", "body\n"), | ||
| 1530 | "changes/" + approvedID + "/approvals/" + f.accountName("keenan") + ".md": approvalFile("main", secondHead), | ||
| 1531 | "changes/" + mergedID + "/change.md": requestFileMerged("Landed change", "main", secondHead, "wilbur", "keenan", nil), | ||
| 1532 | "changes/" + closedID + "/change.md": requestFileState("Dropped change", "main", firstHead, "wilbur", "closed", "body\n"), | ||
| 1533 | "changes/" + followingID + "/change.md": requestFileFollowing("Follows a branch", "main", firstHead, "feature-one", "keenan", "body\n"), | ||
| 1534 | 1534 | }, "changes"); err != nil { | |
| 1535 | 1535 | t.Fatalf("changes push: %v", err) | |
| 1536 | 1536 | } | |