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.

Show open work on repository tabs and overview

a196e404c86a5b9607bd226c7229ffc89a37d47f · Keenan Nemetz · 11d ago · parent 0e35a6a0

Show open work on repository tabs and overview

The repository header now counts open issues and change requests, and the overview sidebar lists the newest open issues and change requests with links to their full lists. Closed and merged records stay out of both: the counts and the overview describe what is still being worked on.

Issue counts come from the derived index; change requests are read from the metadata branch, where their state lives. A failed read leaves a zero or an empty section rather than turning the overview into an error page.

forge/index/issues.go +11−3

@@ -232,9 +232,17 @@ func (s *Store) Assignees(repoID string) ([]string, error) {
232 232 return out, rows.Err()
233 233 }
234 234
235 // IssueCount is used by the repo page.
236 func (s *Store) IssueCount(repoID string) (int, error) {
235 // IssueCount returns the number of issues in a state. An empty state, or "all",
236 // counts every issue. It is used by the repository header, which has to answer
237 // without loading the rows it is counting.
238 func (s *Store) IssueCount(repoID, state string) (int, error) {
239 q := `SELECT COUNT(*) FROM issues WHERE repo_id=?`
240 args := []any{repoID}
241 if state != "" && state != "all" {
242 q += ` AND state=?`
243 args = append(args, state)
244 }
237 245 var n int
238 err := s.db.QueryRow(`SELECT COUNT(*) FROM issues WHERE repo_id=?`, repoID).Scan(&n)
246 err := s.db.QueryRow(q, args...).Scan(&n)
239 247 return n, err
240 248 }