3 files changed,
58 insertions(+),
16 deletions(-)
Author:
Oleksandr Smirnov
olexsmir@gmail.com
Committed at:
2026-01-30 20:54:12 +0200
Authored at:
2026-01-30 19:39:00 +0200
Change ID:
tvqkmkkrplqwqyrmksyyqvpsprypzltk
Parent:
12a019f
M
internal/git/repo.go
路路路 18 18 19 19 // Thanks https://git.icyphox.sh/legit/blob/master/git/git.go 20 20 21 +var ErrEmptyRepo = errors.New("repository has no commits") 22 + 21 23 type Repo struct { 22 24 path string 23 25 r *git.Repository 路路路 37 39 if ref == "" { 38 40 head, err := g.r.Head() 39 41 if err != nil { 42 + if errors.Is(err, plumbing.ErrReferenceNotFound) { 43 + return &g, nil 44 + } 40 45 return nil, fmt.Errorf("getting head of %s: %w", path, err) 41 46 } 42 47 g.h = head.Hash() 路路路 50 55 return &g, nil 51 56 } 52 57 58 +func (g *Repo) IsEmpty() bool { 59 + return g.h == plumbing.ZeroHash 60 +} 61 + 62 +// Init creates a bare repo. 63 +func Init(path string) error { 64 + _, err := git.PlainInit(path, true) 65 + return err 66 +} 67 + 53 68 func (g *Repo) Name() string { 54 69 name := filepath.Base(g.path) 55 70 return strings.TrimSuffix(name, ".git") 56 71 } 57 72 58 73 func (g *Repo) Commits() ([]*object.Commit, error) { 74 + if g.IsEmpty() { 75 + return []*object.Commit{}, nil 76 + } 77 + 59 78 ci, err := g.r.Log(&git.LogOptions{ 60 79 From: g.h, 61 80 Order: git.LogOrderCommitterTime, 路路路 74 93 } 75 94 76 95 func (g *Repo) LastCommit() (*object.Commit, error) { 96 + if g.IsEmpty() { 97 + return nil, ErrEmptyRepo 98 + } 99 + 77 100 c, err := g.r.CommitObject(g.h) 78 101 if err != nil { 79 102 return nil, fmt.Errorf("last commit: %w", err) 路路路 189 212 } 190 213 191 214 func (g *Repo) FindMasterBranch(masters []string) (string, error) { 215 + if g.IsEmpty() { 216 + return "", ErrEmptyRepo 217 + } 218 + 192 219 for _, b := range masters { 193 220 if _, err := g.r.ResolveRevision(plumbing.Revision(b)); err == nil { 194 221 return b, nil
M
internal/handlers/repo.go
路路路 50 50 return 51 51 } 52 52 53 + desc, err := repo.Description() 54 + if err != nil { 55 + h.write500(w, err) 56 + return 57 + } 58 + 59 + data := make(map[string]any) 60 + data["name"] = name 61 + data["desc"] = desc 62 + data["servername"] = h.c.Meta.Host 63 + data["meta"] = h.c.Meta 64 + 65 + if repo.IsEmpty() { 66 + data["empty"] = true 67 + h.templ(w, "repo_index", data) 68 + return 69 + } 70 + 53 71 var readmeContents template.HTML 54 72 for _, readme := range h.c.Repo.Readmes { 55 73 ext := filepath.Ext(readme) 路路路 76 94 return 77 95 } 78 96 79 - desc, err := repo.Description() 80 - if err != nil { 81 - h.write500(w, err) 82 - return 83 - } 84 - 85 97 commits, err := repo.Commits() 86 98 if err != nil { 87 99 h.write500(w, err) 路路路 92 104 commits = commits[:3] 93 105 } 94 106 95 - data := make(map[string]any) 96 - data["name"] = name 97 107 data["ref"] = masterBranch 98 - data["desc"] = desc 99 108 data["readme"] = readmeContents 100 109 data["commits"] = commits 101 - data["servername"] = h.c.Meta.Host 102 - data["meta"] = h.c.Meta 103 110 data["gomod"] = repo.IsGoMod() 104 111 105 112 if mirrorInfo, err := repo.MirrorInfo(); err == nil && mirrorInfo.IsMirror { 路路路 396 403 continue 397 404 } 398 405 399 - lastComit, err := repo.LastCommit() 406 + var lastCommitTime time.Time 407 + lastCommit, err := repo.LastCommit() 400 408 if err != nil { 401 - errs = append(errs, err) 402 - continue 409 + if !errors.Is(err, git.ErrEmptyRepo) { 410 + errs = append(errs, err) 411 + continue 412 + } 413 + } else { 414 + lastCommitTime = lastCommit.Author.When 403 415 } 404 416 405 417 repos = append(repos, repoList{ 406 418 Name: normalizedName, 407 419 Desc: desc, 408 - LastCommit: lastComit.Author.When, 420 + LastCommit: lastCommitTime, 409 421 }) 410 422 } 411 423
M
web/templates/repo_index.html
路路路 10 10 11 11 <main> 12 12 {{ $repo := .name }} 13 - 13 + {{ if .empty }} 14 + <h3>Repository is empty</h3> 15 + {{ else }} 14 16 <section class="repo-index"> 15 17 <div class="repo-index-main"> 16 18 {{ range .commits }} 路路路 42 44 {{- end }} 43 45 </div> 44 46 </section> 47 + {{ end }} 45 48 46 49 {{- if .readme }} 47 50 <article class="readme">