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.
Document how a change request links the issues it closes `vole change new` and `vole change update` take `--closes`, and the request's metadata is what the page shows and what landing the request closes. None of the guides said so: `docs/cli.md` listed neither flag, `docs/change-requests.md` never mentioned the field, and `CONTRIBUTING.md` showed the opening command without it.
a0a7c73a67594f772ad9796dc570d81a68e5ab63 · Keenan Nemetz · 13d ago · parent c765ae2e
Document how a change request links the issues it closes `vole change new` and `vole change update` take `--closes`, and the request's metadata is what the page shows and what landing the request closes. None of the guides said so: `docs/cli.md` listed neither flag, `docs/change-requests.md` never mentioned the field, and `CONTRIBUTING.md` showed the opening command without it. That gap has a cost beyond being incomplete: a description that says `Fixes #<ulid>` looks like it links the issue, so a request can land without closing the issue it was meant to fix, and nobody notices until the issue is still open on a merged change. The workflow guide now has a section on the link — set it at open or while the request is open, replaced rather than appended, full ids that must exist, and only landing closes — the command reference lists the flags, and CONTRIBUTING points at `--closes` and says the prose form is only text.
docs/change-requests.md +32−4
| @@ -7,7 +7,7 @@ so if the branch changes after approval, the approval no longer applies. | |||
| 7 | 7 | ## Files behind a request | |
| 8 | 8 | ||
| 9 | 9 | ```text | |
| 10 | requests/<ulid>/request.md # title, state, author, base, head | ||
| 10 | requests/<ulid>/request.md # title, state, author, base, head, closes | ||
| 11 | 11 | requests/<ulid>/comments/<ulid>.md # discussion | |
| 12 | 12 | requests/<ulid>/approvals/<account-name>.md # one approval per account | |
| 13 | 13 | ``` | |
| @@ -26,9 +26,10 @@ repository page. | |||
| 26 | 26 | Maintainers can still use the CLI: | |
| 27 | 27 | ||
| 28 | 28 | ```sh | |
| 29 | # The author pushes a branch and opens a request. | ||
| 29 | # The author pushes a branch and opens a request for the issue it fixes. | ||
| 30 | 30 | git push origin feature:refs/heads/feature | |
| 31 | vole change new --title "Retry on timeout" --base main --head feature -m "Rationale." | ||
| 31 | vole change new --title "Retry on timeout" --base main --head feature \ | ||
| 32 | --closes 01M5JR2JK29KKMAA1T9MDNTPBP -m "Rationale." | ||
| 32 | 33 | ||
| 33 | 34 | # An approver reviews that commit and approves it. | |
| 34 | 35 | vole change approve <id> --as <your-name> | |
| @@ -42,7 +43,7 @@ Other commands: | |||
| 42 | 43 | ```sh | |
| 43 | 44 | vole change list [--state open|closed] | |
| 44 | 45 | vole change show <id> | |
| 45 | vole change update <id> --head <rev> | ||
| 46 | vole change update <id> [--head <rev>] [--closes <issue>]... [--no-closes] | ||
| 46 | 47 | vole change close <id> | |
| 47 | 48 | vole change reopen <id> | |
| 48 | 49 | ``` | |
| @@ -51,6 +52,33 @@ vole change reopen <id> | |||
| 51 | 52 | needed commits are available locally. If they are not, it says so rather than | |
| 52 | 53 | guessing. | |
| 53 | 54 | ||
| 55 | ## Linking the issues it closes | ||
| 56 | |||
| 57 | A change request names the issues it fixes in its own metadata, not in its | ||
| 58 | description: `request.md` carries a `closes` list, the request page shows those | ||
| 59 | issues, and landing the request closes them in the same commit that marks it | ||
| 60 | merged. A `#<ulid>` or `Fixes #<ulid>` in the description is only prose — it does | ||
| 61 | not link anything and closes nothing. | ||
| 62 | |||
| 63 | Set the list when the request is opened, or later while it is still open: | ||
| 64 | |||
| 65 | ```sh | ||
| 66 | vole change new --title "Retry on timeout" --base main --head feature \ | ||
| 67 | --closes 01M5JR2JK29KKMAA1T9MDNTPBP,01M5N1PRC4GJPZNEEG8PR8J4D6 | ||
| 68 | vole change update <id> --closes 01M5JR2JK29KKMAA1T9MDNTPBP # replace the list | ||
| 69 | vole change update <id> --no-closes # clear it | ||
| 70 | ``` | ||
| 71 | |||
| 72 | Ids are full 26-character ULIDs, and the issue has to exist when the link is | ||
| 73 | written, so a typo fails while the author is still looking at the command. The | ||
| 74 | browser's **Open change request** form takes the same list in its **Closes** | ||
| 75 | field. | ||
| 76 | |||
| 77 | Only an open request may be relinked: a merged request's list records what the | ||
| 78 | merge did, and a closed one is not going to land. Landing is what closes an | ||
| 79 | issue; linking one does not, and a request that is closed without landing leaves | ||
| 80 | its issues open. | ||
| 81 | |||
| 54 | 82 | ## How approvals work | |
| 55 | 83 | ||
| 56 | 84 | A protected branch only accepts an update if the new tip is the approved commit, | |