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.
Open one file at a time on the commit page
628d45239eb09af4e46c9dc779d30144e96c7e6f · Keenan Nemetz · 11d ago · parent 816cc543
Open one file at a time on the commit page
A commit page rendered every patch it contained, so a broad commit turned one
page load into every blob it touched. It now opens the file tree beside the diff
of a single file, the same shape a change request's Files tab uses: the tree is
built from `git show --name-status`, only the selected path's patch is read, and
a tree click swaps the pane over HTMX. `/commit/{sha}/{path}` deep-links a file
and a 512 KiB cap still bounds one file's patch.
The file tree became one widget for three surfaces rather than two, so its
context gained a Commit field and its href/target/status rules moved onto the
view (Branch, Diff, Href).
The pane's header is now one row: the file's name on the left and its line
counts on the right, with the separate "1 file changed" summary line dropped
when a single file fills the pane. The total-line remains for the multi-file
diff a compare renders.
server/web/request_files.go +6−6
| @@ -19,9 +19,9 @@ import ( | |||
| 19 | 19 | "github.com/rodent-software/vole/metadata" | |
| 20 | 20 | ) | |
| 21 | 21 | ||
| 22 | // reviewFilePath is the path a changed file is known by in the review tree. | ||
| 22 | // diffFilePath is the path a changed file is known by in a changed-file tree. | ||
| 23 | 23 | // Deleted files only have their old path; everything else uses the new one. | |
| 24 | func reviewFilePath(f diffFile) string { | ||
| 24 | func diffFilePath(f diffFile) string { | ||
| 25 | 25 | if f.NewPath != "" { | |
| 26 | 26 | return f.NewPath | |
| 27 | 27 | } | |
| @@ -53,7 +53,7 @@ func reviewFileStatus(f diffFile) string { | |||
| 53 | 53 | func buildReviewTree(files []diffFile, active string) []*treeNode { | |
| 54 | 54 | root := &treeNode{Type: "tree"} | |
| 55 | 55 | for _, f := range files { | |
| 56 | path := reviewFilePath(f) | ||
| 56 | path := diffFilePath(f) | ||
| 57 | 57 | if path == "" { | |
| 58 | 58 | continue | |
| 59 | 59 | } | |
| @@ -128,11 +128,11 @@ func (w *Web) RequestFiles(rw http.ResponseWriter, r *http.Request) { | |||
| 128 | 128 | ||
| 129 | 129 | selected := r.PathValue("path") | |
| 130 | 130 | if selected == "" && len(files) > 0 { | |
| 131 | selected = reviewFilePath(files[0]) | ||
| 131 | selected = diffFilePath(files[0]) | ||
| 132 | 132 | } | |
| 133 | 133 | var chosen *diffFile | |
| 134 | 134 | for i := range files { | |
| 135 | if reviewFilePath(files[i]) == selected { | ||
| 135 | if diffFilePath(files[i]) == selected { | ||
| 136 | 136 | chosen = &files[i] | |
| 137 | 137 | break | |
| 138 | 138 | } | |
| @@ -144,7 +144,7 @@ func (w *Web) RequestFiles(rw http.ResponseWriter, r *http.Request) { | |||
| 144 | 144 | ||
| 145 | 145 | active := "" | |
| 146 | 146 | if chosen != nil { | |
| 147 | active = reviewFilePath(*chosen) | ||
| 147 | active = diffFilePath(*chosen) | ||
| 148 | 148 | } | |
| 149 | 149 | main := reviewMainView{ | |
| 150 | 150 | Name: m.Name, | |