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.

Record the default branch summary when a push lands

8dc56e4e258dd56e2c20776f80d61dbed4993f31 · Keenan Nemetz · 10d ago · parent 20442b59

Record the default branch summary when a push lands

The landing card showed the default branch tip and the language it is
mostly made of by running `symbolic-ref`, `rev-parse`, `log -1` and
`ls-tree -r` per repository on every home page read. Those facts change
only when a push moves the branch, so the push now records them.

- `repos` carries head_sha, head_subject, head_author, head_when,
  language and lang_class, and `Index.Entry` returns them with the rest of
  the row.
- `Store.RefreshHead` recomputes the summary and skips the tree walk when
  the recorded tip is still the branch tip, so a metadata or tag push
  costs one rev-parse. It runs from post-receive, from the rebuild, and
  after the default branch changes in settings.
- The language mapping moved to `internal/lang`, shared by the web pages
  and the summary; `fileClass` and `languageFor` are now one table.
- The home cards read the head, language, counts, ACL and newest event
  time from the index. The home page starts no git process at all; the
  all-git card builder stays as the fallback for a Web without an index.

Load harness at concurrency 4 with three repositories: home goes from 243
to 749 req/s, p50 from 16 ms to 5 ms, and the server runs no git child
process for those requests.

server/web/file_icons_test.go +6−2

@@ -1,6 +1,10 @@
1 1 package web
2 2
3 import "testing"
3 import (
4 "testing"
5
6 "github.com/rodent-software/vole/internal/lang"
7 )
4 8
5 9 func TestFileIconsChooseByExtension(t *testing.T) {
6 10 t.Parallel()
@@ -20,7 +24,7 @@ func TestFileIconsChooseByExtension(t *testing.T) {
20 24 if got := fileIcon(c.name); got != c.icon {
21 25 t.Errorf("%s icon = %q, want %q", c.name, got, c.icon)
22 26 }
23 if got := fileClass(c.name); got != c.class {
27 if got := lang.Class(c.name); got != c.class {
24 28 t.Errorf("%s class = %q, want %q", c.name, got, c.class)
25 29 }
26 30 if _, ok := iconPaths[c.icon]; !ok {