all repos

mugit @ e61accc

🐮 git server that your cow will love
10 files changed, 271 insertions(+), 224 deletions(-)
ui: refactor how data is passed to pages
Author: Oleksandr Smirnov olexsmir@gmail.com
Committed at: 2026-02-20 21:24:04 +0200
Authored at: 2026-02-20 21:21:37 +0200
Change ID: quxxpnkrkpsusuonusotlxrzormroouv
Parent: 8fee104
M internal/handlers/repo.go
···
        23
        23
         	"olexsmir.xyz/mugit/internal/mdx"

      
        24
        24
         )

      
        25
        25
         

      
        
        26
        +type Meta struct {

      
        
        27
        +	Title       string

      
        
        28
        +	Description string

      
        
        29
        +	Host        string

      
        
        30
        +	IsEmpty     bool

      
        
        31
        +	GoMod       bool

      
        
        32
        +	SSHEnabled  bool

      
        
        33
        +}

      
        
        34
        +

      
        
        35
        +type RepoBase struct {

      
        
        36
        +	Ref  string

      
        
        37
        +	Desc string

      
        
        38
        +}

      
        
        39
        +

      
        
        40
        +type PageData[T any] struct {

      
        
        41
        +	Meta     Meta

      
        
        42
        +	RepoName string // empty for non-repo pages, needed for _head.html to  compile

      
        
        43
        +	P        T

      
        
        44
        +}

      
        
        45
        +

      
        26
        46
         func (h *handlers) indexHandler(w http.ResponseWriter, r *http.Request) {

      
        27
        47
         	repos, err := h.listPublicRepos()

      
        28
        48
         	if err != nil {

      
        29
        49
         		h.write500(w, err)

      
        30
        50
         		return

      
        31
        51
         	}

      
        
        52
        +	h.templ(w, "index", h.pageData(nil, repos))

      
        
        53
        +}

      
        32
        54
         

      
        33
        
        -	data := make(map[string]any)

      
        34
        
        -	data["meta"] = h.c.Meta

      
        35
        
        -	data["repos"] = repos

      
        36
        
        -	data["servername"] = h.c.Meta.Host

      
        37
        
        -	h.templ(w, "index", data)

      
        
        55
        +type RepoIndex struct {

      
        
        56
        +	Desc           string

      
        
        57
        +	IsEmpty        bool

      
        
        58
        +	Readme         template.HTML

      
        
        59
        +	Ref            string

      
        
        60
        +	Commits        []*git.Commit

      
        
        61
        +	IsMirror       bool

      
        
        62
        +	MirrorURL      string

      
        
        63
        +	MirrorLastSync time.Time

      
        38
        64
         }

      
        39
        65
         

      
        40
        66
         func (h *handlers) repoIndex(w http.ResponseWriter, r *http.Request) {

      ···
        50
        76
         		return

      
        51
        77
         	}

      
        52
        78
         

      
        53
        
        -	data := make(map[string]any)

      
        54
        
        -	data["name"] = repo.Name()

      
        55
        
        -	data["desc"] = desc

      
        56
        
        -	data["servername"] = h.c.Meta.Host

      
        57
        
        -	data["meta"] = h.c.Meta

      
        58
        
        -

      
        59
        
        -	if repo.IsEmpty() {

      
        60
        
        -		data["empty"] = true

      
        61
        
        -		h.templ(w, "repo_index", data)

      
        
        79
        +	p := RepoIndex{Desc: desc, IsEmpty: repo.IsEmpty()}

      
        
        80
        +	if p.IsEmpty {

      
        
        81
        +		h.templ(w, "repo_index", h.pageData(repo, p))

      
        62
        82
         		return

      
        63
        83
         	}

      
        64
        84
         

      
        65
        
        -	masterBranch, err := repo.FindMasterBranch(h.c.Repo.Masters)

      
        
        85
        +	p.Ref, err = repo.FindMasterBranch(h.c.Repo.Masters)

      
        66
        86
         	if err != nil {

      
        67
        87
         		h.write500(w, err)

      
        68
        88
         		return

      
        69
        89
         	}

      
        70
        90
         

      
        71
        
        -	readme, err := h.renderReadme(repo)

      
        
        91
        +	p.Readme, err = h.renderReadme(repo)

      
        72
        92
         	if err != nil {

      
        73
        93
         		h.write500(w, err)

      
        74
        94
         		return

      
        75
        95
         	}

      
        76
        96
         

      
        77
        
        -	commits, err := repo.Commits()

      
        
        97
        +	p.Commits, err = repo.Commits()

      
        78
        98
         	if err != nil {

      
        79
        99
         		h.write500(w, err)

      
        80
        100
         		return

      
        81
        101
         	}

      
        82
        102
         

      
        83
        
        -	if len(commits) >= 4 {

      
        84
        
        -		commits = commits[:3]

      
        
        103
        +	if len(p.Commits) >= 3 {

      
        
        104
        +		p.Commits = p.Commits[:3]

      
        85
        105
         	}

      
        86
        106
         

      
        87
        
        -	data["ref"] = masterBranch

      
        88
        
        -	data["readme"] = readme

      
        89
        
        -	data["commits"] = commits

      
        90
        
        -	data["gomod"] = repo.IsGoMod()

      
        
        107
        +	if isMirror, err := repo.IsMirror(); isMirror && err == nil {

      
        
        108
        +		p.IsMirror = true

      
        
        109
        +		p.MirrorURL, _ = repo.RemoteURL()

      
        
        110
        +		p.MirrorLastSync, _ = repo.LastSync()

      
        
        111
        +	}

      
        91
        112
         

      
        92
        
        -	if isMirror, err := repo.IsMirror(); err == nil && isMirror {

      
        93
        
        -		lastSync, _ := repo.LastSync()

      
        94
        
        -		remoteURL, _ := repo.RemoteURL()

      
        95
        
        -		data["mirrorinfo"] = map[string]any{

      
        96
        
        -			"isMirror": true,

      
        97
        
        -			"url":      remoteURL,

      
        98
        
        -			"lastSync": lastSync,

      
        99
        
        -		}

      
        100
        
        -	}

      
        
        113
        +	h.templ(w, "repo_index", h.pageData(repo, p))

      
        
        114
        +}

      
        101
        115
         

      
        102
        
        -	h.templ(w, "repo_index", data)

      
        
        116
        +type RepoTree struct {

      
        
        117
        +	Desc       string

      
        
        118
        +	Ref        string

      
        
        119
        +	Tree       []git.NiceTree

      
        
        120
        +	ParentPath string

      
        
        121
        +	DotDot     string

      
        
        122
        +	Readme     template.HTML

      
        103
        123
         }

      
        104
        124
         

      
        105
        125
         func (h *handlers) repoTreeHandler(w http.ResponseWriter, r *http.Request) {

      ···
        119
        139
         		return

      
        120
        140
         	}

      
        121
        141
         

      
        122
        
        -	files, err := repo.FileTree(treePath)

      
        
        142
        +	tree, err := repo.FileTree(treePath)

      
        123
        143
         	if err != nil {

      
        124
        144
         		h.write500(w, err)

      
        125
        145
         		return

      
        126
        146
         	}

      
        127
        147
         

      
        128
        
        -	data := make(map[string]any)

      
        129
        
        -	data["name"] = name

      
        130
        
        -	data["ref"] = ref

      
        131
        
        -	data["parent"] = treePath

      
        132
        
        -	data["dotdot"] = filepath.Dir(treePath)

      
        133
        
        -	data["desc"] = desc

      
        134
        
        -	data["meta"] = h.c.Meta

      
        135
        
        -	data["files"] = files

      
        
        148
        +	h.templ(w, "repo_tree", h.pageData(repo, RepoTree{

      
        
        149
        +		Desc:       desc,

      
        
        150
        +		Ref:        ref,

      
        
        151
        +		Tree:       tree,

      
        
        152
        +		ParentPath: treePath,

      
        
        153
        +		DotDot:     filepath.Dir(treePath),

      
        
        154
        +		// TODO: return the readme

      
        
        155
        +		Readme: "",

      
        
        156
        +	}))

      
        
        157
        +}

      
        136
        158
         

      
        137
        
        -	h.templ(w, "repo_tree", data)

      
        
        159
        +type RepoFile struct {

      
        
        160
        +	Ref       string

      
        
        161
        +	Desc      string

      
        
        162
        +	LineCount []int

      
        
        163
        +	Path      string

      
        
        164
        +	IsImage   bool

      
        
        165
        +	IsBinary  bool

      
        
        166
        +	Content   string

      
        
        167
        +	Mime      string

      
        
        168
        +	Size      int64

      
        138
        169
         }

      
        139
        170
         

      
        140
        171
         func (h *handlers) fileContentsHandler(w http.ResponseWriter, r *http.Request) {

      ···
        150
        181
         	repo, err := h.openPublicRepo(name, ref)

      
        151
        182
         	if err != nil {

      
        152
        183
         		h.write404(w, err)

      
        153
        
        -		return

      
        154
        
        -	}

      
        155
        
        -

      
        156
        
        -	desc, err := repo.Description()

      
        157
        
        -	if err != nil {

      
        158
        
        -		h.write500(w, err)

      
        159
        184
         		return

      
        160
        185
         	}

      
        161
        186
         

      ···
        176
        201
         		return

      
        177
        202
         	}

      
        178
        203
         

      
        179
        
        -	if fc.IsImage() || fc.IsBinary {

      
        180
        
        -		data := make(map[string]any)

      
        181
        
        -		data["name"] = name

      
        182
        
        -		data["ref"] = ref

      
        183
        
        -		data["desc"] = desc

      
        184
        
        -		data["path"] = treePath

      
        185
        
        -		data["is_image"] = fc.IsImage()

      
        186
        
        -		data["is_binary"] = fc.IsBinary

      
        187
        
        -		data["mime_type"] = fc.Mime

      
        188
        
        -		data["size"] = fc.Size

      
        189
        
        -		data["meta"] = h.c.Meta

      
        190
        
        -		h.templ(w, "repo_file", data)

      
        191
        
        -		return

      
        
        204
        +	p := RepoFile{

      
        
        205
        +		Ref:      ref,

      
        
        206
        +		Path:     treePath,

      
        
        207
        +		IsImage:  fc.IsImage(),

      
        
        208
        +		IsBinary: fc.IsBinary,

      
        
        209
        +		Mime:     fc.Mime,

      
        
        210
        +		Size:     fc.Size,

      
        192
        211
         	}

      
        193
        212
         

      
        194
        
        -	data := make(map[string]any)

      
        195
        
        -	data["name"] = name

      
        196
        
        -	data["ref"] = ref

      
        197
        
        -	data["desc"] = desc

      
        198
        
        -	data["path"] = treePath

      
        199
        
        -

      
        200
        
        -	contentStr := fc.String()

      
        201
        
        -	lc, err := countLines(strings.NewReader(contentStr))

      
        
        213
        +	p.Desc, err = repo.Description()

      
        202
        214
         	if err != nil {

      
        203
        
        -		slog.Error("failed to count line numbers", "err", err)

      
        
        215
        +		h.write500(w, err)

      
        
        216
        +		return

      
        204
        217
         	}

      
        205
        218
         

      
        206
        
        -	lines := make([]int, lc)

      
        207
        
        -	if lc > 0 {

      
        
        219
        +	if !fc.IsImage() && !fc.IsBinary {

      
        
        220
        +		contentStr := fc.String()

      
        
        221
        +		lc, err := countLines(strings.NewReader(contentStr))

      
        
        222
        +		if err != nil {

      
        
        223
        +			slog.Error("failed to count line numbers", "err", err)

      
        
        224
        +		}

      
        
        225
        +		lines := make([]int, lc)

      
        208
        226
         		for i := range lines {

      
        209
        227
         			lines[i] = i + 1

      
        210
        228
         		}

      
        
        229
        +		p.Content = contentStr

      
        
        230
        +		p.LineCount = lines

      
        211
        231
         	}

      
        212
        232
         

      
        213
        
        -	data["linecount"] = lines

      
        214
        
        -	data["content"] = contentStr

      
        215
        
        -	data["meta"] = h.c.Meta

      
        
        233
        +	h.templ(w, "repo_file", h.pageData(repo, p))

      
        
        234
        +}

      
        216
        235
         

      
        217
        
        -	h.templ(w, "repo_file", data)

      
        
        236
        +type RepoLog struct {

      
        
        237
        +	Desc    string

      
        
        238
        +	Commits []*git.Commit

      
        
        239
        +	Ref     string

      
        218
        240
         }

      
        219
        241
         

      
        220
        242
         func (h *handlers) logHandler(w http.ResponseWriter, r *http.Request) {

      ···
        239
        261
         		return

      
        240
        262
         	}

      
        241
        263
         

      
        242
        
        -	data := make(map[string]any)

      
        243
        
        -	data["name"] = name

      
        244
        
        -	data["ref"] = ref

      
        245
        
        -	data["desc"] = desc

      
        246
        
        -	data["meta"] = h.c.Meta

      
        247
        
        -	data["log"] = true

      
        248
        
        -	data["commits"] = commits

      
        249
        
        -	h.templ(w, "repo_log", data)

      
        
        264
        +	h.templ(w, "repo_log", h.pageData(repo, RepoLog{

      
        
        265
        +		Desc:    desc,

      
        
        266
        +		Commits: commits,

      
        
        267
        +		Ref:     ref,

      
        
        268
        +	}))

      
        
        269
        +}

      
        
        270
        +

      
        
        271
        +type RepoCommit struct {

      
        
        272
        +	Diff *git.NiceDiff

      
        
        273
        +	Ref  string

      
        
        274
        +	Desc string

      
        250
        275
         }

      
        251
        276
         

      
        252
        277
         func (h *handlers) commitHandler(w http.ResponseWriter, r *http.Request) {

      ···
        270
        295
         		return

      
        271
        296
         	}

      
        272
        297
         

      
        273
        
        -	data := make(map[string]any)

      
        274
        
        -	data["diff"] = diff.Diff

      
        275
        
        -	data["commit"] = diff.Commit

      
        276
        
        -	data["parents"] = diff.Parents

      
        277
        
        -	data["stat"] = diff.Stat

      
        278
        
        -	data["name"] = name

      
        279
        
        -	data["ref"] = ref

      
        280
        
        -	data["desc"] = desc

      
        281
        
        -	h.templ(w, "repo_commit", data)

      
        
        298
        +	h.templ(w, "repo_commit", h.pageData(repo, RepoCommit{

      
        
        299
        +		Desc: desc,

      
        
        300
        +		Ref:  ref,

      
        
        301
        +		Diff: diff,

      
        
        302
        +	}))

      
        
        303
        +}

      
        
        304
        +

      
        
        305
        +type RepoRefs struct {

      
        
        306
        +	Desc     string

      
        
        307
        +	Ref      string

      
        
        308
        +	Branches []*git.Branch

      
        
        309
        +	Tags     []*git.TagReference

      
        282
        310
         }

      
        283
        311
         

      
        284
        312
         func (h *handlers) refsHandler(w http.ResponseWriter, r *http.Request) {

      ···
        294
        322
         		return

      
        295
        323
         	}

      
        296
        324
         

      
        297
        
        -	masterBranch, err := repo.FindMasterBranch(h.c.Repo.Masters)

      
        
        325
        +	master, err := repo.FindMasterBranch(h.c.Repo.Masters)

      
        298
        326
         	if err != nil {

      
        299
        327
         		h.write500(w, err)

      
        300
        328
         		return

      ···
        306
        334
         		return

      
        307
        335
         	}

      
        308
        336
         

      
        309
        
        -	tags, err := repo.Tags()

      
        310
        
        -	if err != nil {

      
        311
        
        -		// repo should have at least one branch, tags are *optional*

      
        312
        
        -		slog.Error("couldn't fetch repo tags", "err", err)

      
        313
        
        -	}

      
        
        337
        +	// repo should have at least one branch, tags are *optional*

      
        
        338
        +	tags, _ := repo.Tags()

      
        314
        339
         

      
        315
        
        -	data := make(map[string]any)

      
        316
        
        -	data["meta"] = h.c.Meta

      
        317
        
        -	data["name"] = repo.Name()

      
        318
        
        -	data["desc"] = desc

      
        319
        
        -	data["ref"] = masterBranch

      
        320
        
        -	data["branches"] = branches

      
        321
        
        -	data["tags"] = tags

      
        322
        
        -	h.templ(w, "repo_refs", data)

      
        
        340
        +	h.templ(w, "repo_refs", h.pageData(repo, RepoRefs{

      
        
        341
        +		Desc:     desc,

      
        
        342
        +		Ref:      master,

      
        
        343
        +		Tags:     tags,

      
        
        344
        +		Branches: branches,

      
        
        345
        +	}))

      
        323
        346
         }

      
        324
        347
         

      
        325
        348
         func countLines(r io.Reader) (int, error) {

      ···
        452
        475
         	h.readmeCache.Set(name, readmeContents)

      
        453
        476
         	return readmeContents, nil

      
        454
        477
         }

      
        
        478
        +

      
        
        479
        +func (h handlers) pageData(repo *git.Repo, p any) PageData[any] {

      
        
        480
        +	var name string

      
        
        481
        +	var gomod, empty bool

      
        
        482
        +	if repo != nil {

      
        
        483
        +		gomod = repo.IsGoMod()

      
        
        484
        +		empty = repo.IsEmpty()

      
        
        485
        +		name = repo.Name()

      
        
        486
        +	}

      
        
        487
        +

      
        
        488
        +	return PageData[any]{

      
        
        489
        +		P:        p,

      
        
        490
        +		RepoName: name,

      
        
        491
        +		Meta: Meta{

      
        
        492
        +			Title:       h.c.Meta.Title,

      
        
        493
        +			Description: h.c.Meta.Description,

      
        
        494
        +			Host:        h.c.Meta.Host,

      
        
        495
        +			GoMod:       gomod,

      
        
        496
        +			SSHEnabled:  h.c.SSH.Enable,

      
        
        497
        +			IsEmpty:     empty,

      
        
        498
        +		},

      
        
        499
        +	}

      
        
        500
        +}

      
M web/templates/_head.html
···
        3
        3
           <meta name="viewport" content="width=device-width, initial-scale=1">

      
        4
        4
           <link rel="stylesheet" href="/static/style.css" type="text/css">

      
        5
        5
           <link rel="icon" href="/static/favicon.svg">

      
        6
        
        -  {{ if and .servername .gomod }}

      
        7
        
        -  <meta name="go-import" content="{{ .servername}}/{{ .name }} git https://{{ .servername }}/{{ .name }}">

      
        8
        
        -  {{ end }}

      
        9
        
        -  {{ if and .servername .name }}

      
        10
        
        -  <link rel="alternate" type="application/rss" href="https://{{ .servername }}/{{ .name }}/feed">

      
        
        6
        +

      
        
        7
        +  {{ if .Meta.GoMod }}

      
        
        8
        +  <meta name="go-import" content="{{.Meta.Host}}/{{.RepoName}} git https://{{.Meta.Host}}/{{.RepoName}}">

      
        11
        9
           {{ end }}

      
        12
        
        -  {{ if .servername }}

      
        13
        
        -  <link rel="alternate" type="application/rss" href="https://{{ .servername }}/index.xml">

      
        
        10
        +

      
        
        11
        +  <link ref="alternate" type="application/rss" href="https://{{.Meta.Host}}/index.xml">

      
        
        12
        +  {{ if .RepoName }}

      
        
        13
        +  <link ref="alternate" type="application/rss" href="https://{{.Meta.Host}}/{{.RepoName}}/feed">

      
        14
        14
           {{ end }}

      
        15
        15
         {{ end }}

      
M web/templates/_repo_header.html
···
        4
        4
             <a href="/">all repos</a>

      
        5
        5
           </div>

      
        6
        6
           <h1 class="repo-name">

      
        7
        
        -    {{ .name }}

      
        8
        
        -    {{- if .ref }}

      
        9
        
        -    <span class="ref">@ {{ .ref }}</span>

      
        
        7
        +    {{ .RepoName }}

      
        
        8
        +    {{- if .P.Ref }}

      
        
        9
        +    <span class="ref">@ {{ .P.Ref }}</span>

      
        10
        10
             {{- end }}

      
        11
        11
           </h1>

      
        12
        
        -  {{- if .desc }}

      
        13
        
        -  <div class="desc muted">{{ .desc }}</div>

      
        
        12
        +  {{- if .P.Desc }}

      
        
        13
        +  <div class="desc muted">{{ .P.Desc }}</div>

      
        14
        14
           {{- end }}

      
        15
        15
         

      
        16
        
        -  {{- if not .empty }}

      
        
        16
        +  {{- if not .Meta.IsEmpty }}

      
        17
        17
           <nav class="repo-nav">

      
        18
        18
             <ul>

      
        19
        
        -      <li><a href="/{{ .name }}">summary</a></li>

      
        20
        
        -      <li><a href="/{{ .name }}/refs">refs</a></li>

      
        21
        
        -      <li><a href="/{{ .name }}/tree/{{ .ref }}/">tree</a></li>

      
        22
        
        -      <li><a href="/{{ .name }}/log/{{ .ref }}">log</a></li>

      
        
        19
        +      <li><a href="/{{ .RepoName }}">summary</a></li>

      
        
        20
        +      <li><a href="/{{ .RepoName }}/refs">refs</a></li>

      
        
        21
        +      <li><a href="/{{ .RepoName }}/tree/{{ .P.Ref }}/">tree</a></li>

      
        
        22
        +      <li><a href="/{{ .RepoName }}/log/{{ .P.Ref }}">log</a></li>

      
        23
        23
             </ul>

      
        24
        24
           </nav>

      
        25
        25
           {{- end }}

      
M web/templates/index.html
···
        3
        3
         <html>

      
        4
        4
           <head>

      
        5
        5
             {{ template "head" . }}

      
        6
        
        -    <title>{{ .meta.Title }}</title>

      
        
        6
        +    <title>{{ .Meta.Title }}</title>

      
        7
        7
           </head>

      
        8
        8
           <body>

      
        9
        9
             <header>

      
        10
        
        -      <h1>{{ .meta.Title }}</h1>

      
        11
        
        -      {{ if .meta.Description }}<h2>{{ .meta.Description }}</h2>{{ end }}

      
        
        10
        +      <h1>{{ .Meta.Title }}</h1>

      
        
        11
        +      {{ if .Meta.Description }}<h2>{{ .Meta.Description }}</h2>{{ end }}

      
        12
        12
             </header>

      
        13
        13
             <main>

      
        14
        14
               <table class="table index">

      ···
        20
        20
                   </tr>

      
        21
        21
                 </thead>

      
        22
        22
                 <tbody>

      
        23
        
        -          {{- range .repos }}

      
        
        23
        +          {{- range .P }}

      
        24
        24
                   <tr>

      
        25
        25
                     <td class="nowrap"><a href="/{{ .Name }}">{{ .Name }}</a></td>

      
        26
        26
                     <td class="fill">

      
M web/templates/repo_commit.html
···
        1
        1
         {{ define "repo_commit" }}

      
        
        2
        +{{ $commit := .P.Diff.Commit }}

      
        
        3
        +{{ $diff := .P.Diff.Diff }}

      
        
        4
        +{{ $stat := .P.Diff.Stat }}

      
        
        5
        +{{ $parents := .P.Diff.Parents }}

      
        2
        6
         <html>

      
        3
        7
           <head>

      
        4
        8
             {{ template "head" . }}

      
        5
        
        -    <title>{{ .name }}: {{ .commit.HashShort }}</title>

      
        
        9
        +    <title>{{ .RepoName }}: {{ $commit.HashShort }}</title>

      
        6
        10
           </head>

      
        7
        11
           <body>

      
        8
        12
             {{ template "repo_header" . }}

      
        9
        13
             <main>

      
        10
        14
               <section class="commit">

      
        11
        15
                 <div class="commit-refs">

      
        12
        
        -          {{ .stat.FilesChanged }} files changed,

      
        13
        
        -          {{ .stat.Insertions }} insertions(+),

      
        14
        
        -          {{ .stat.Deletions }} deletions(-)

      
        
        16
        +          {{ $stat.FilesChanged }} files changed,

      
        
        17
        +          {{ $stat.Insertions }} insertions(+),

      
        
        18
        +          {{ $stat.Deletions }} deletions(-)

      
        15
        19
                 </div>

      
        16
        20
         

      
        17
        21
                 <div class="box">

      
        18
        22
                   <pre class="commit-message">

      
        19
        
        -            {{- if .commit.Message }}{{- .commit.Message -}}

      
        
        23
        +            {{- if $commit.Message }}{{- $commit.Message -}}

      
        20
        24
                     {{- else -}}<span class="muted">Empty message</span>{{- end -}}

      
        21
        25
                   </pre>

      
        22
        26
                   <div>

      
        23
        27
                     <strong>Author:</strong>

      
        24
        
        -            {{ .commit.AuthorName }}

      
        25
        
        -            <a href="mailto:{{ .AuthorEmail }}" class="commit-email">{{ .commit.AuthorEmail }}</a>

      
        
        28
        +            {{ $commit.AuthorName }}

      
        
        29
        +            <a href="mailto:{{ $commit.AuthorEmail }}" class="commit-email">{{ $commit.AuthorEmail }}</a>

      
        26
        30
                   </div>

      
        27
        31
                   <div>

      
        28
        32
                     <strong>Committed at:</strong>

      
        29
        
        -            {{ .commit.Committed }}

      
        
        33
        +            {{ $commit.Committed }}

      
        30
        34
                   </div>

      
        31
        
        -          {{ if .commit.ChangeID -}}

      
        
        35
        +          {{ if $commit.ChangeID -}}

      
        32
        36
                   <div>

      
        33
        37
                     <strong>Change ID:</strong>

      
        34
        
        -            {{ .commit.ChangeID }}

      
        
        38
        +            {{ $commit.ChangeID }}

      
        35
        39
                   </div>

      
        36
        40
                   {{- end }}

      
        37
        41
                   <div>

      
        38
        42
                     <strong>Parent:</strong>

      
        39
        
        -            {{ range $i, $p := .parents -}}

      
        
        43
        +            {{ range $i, $p := $parents -}}

      
        40
        44
                     {{ if $i }}, {{ end -}}

      
        41
        
        -            <a class="link" href="/{{ $.name }}/commit/{{ $p }}">{{ $p }}</a>

      
        
        45
        +            <a class="link" href="/{{$.RepoName}}/commit/{{ $p }}">{{ $p }}</a>

      
        42
        46
                     {{- end }}

      
        43
        47
                   </div>

      
        44
        48
                 </div>

      
        45
        49
         

      
        46
        
        -        {{ if gt (len .diff) 1 -}}

      
        
        50
        +        {{ if gt (len $diff) 1 -}}

      
        47
        51
                 <div class="jump">

      
        48
        52
                   <strong>jump to</strong>

      
        49
        53
                   <table class="table jump-table">

      
        50
        54
                     <tbody>

      
        51
        
        -              {{ range .diff }}

      
        
        55
        +              {{ range $diff }}

      
        52
        56
                       {{ $path := .Name.New }}

      
        53
        57
                       {{ if not $path }}{{ $path = .Name.Old }}{{ end }}

      
        54
        58
                       <tr>

      ···
        70
        74
                 {{ end }}

      
        71
        75
               </section>

      
        72
        76
               <section>

      
        73
        
        -        {{ $repo := .name }}

      
        74
        
        -        {{ $this := .commit.Hash }}

      
        75
        
        -        {{ $parent := index .parents 0 }}

      
        76
        
        -        {{ range .diff }}

      
        
        77
        +        {{ $this := $commit.Hash }}

      
        
        78
        +        {{ $parent := index $parents 0 }}

      
        
        79
        +        {{ range $diff }}

      
        77
        80
                 {{ $path := .Name.New }}

      
        78
        81
                 {{ if not $path }}{{ $path = .Name.Old }}{{ end }}

      
        79
        82
                 <div id="{{ $path }}">

      ···
        88
        91
                     <span class="diff-type diff-mod">M</span>

      
        89
        92
                     {{ end }}

      
        90
        93
                     {{ if .Name.Old }}

      
        91
        
        -            <a href="/{{ $repo }}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a>

      
        
        94
        +            <a href="/{{$.RepoName}}/blob/{{ $parent }}/{{ .Name.Old }}">{{ .Name.Old }}</a>

      
        92
        95
                     {{ if .Name.New }}

      
        93
        96
                     &#8594;

      
        94
        
        -            <a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>

      
        
        97
        +            <a href="/{{$.RepoName}}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>

      
        95
        98
                     {{ end }}

      
        96
        99
                     {{ else }}

      
        97
        
        -            <a href="/{{ $repo }}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>

      
        
        100
        +            <a href="/{{$.RepoName}}/blob/{{ $this }}/{{ .Name.New }}">{{ .Name.New }}</a>

      
        98
        101
                     {{- end -}}

      
        99
        102
                     {{ if .IsBinary }}

      
        100
        103
                     <p>Not showing binary file.</p>

      
M web/templates/repo_file.html
···
        2
        2
         <html>

      
        3
        3
           <head>

      
        4
        4
             {{ template "head" . }}

      
        5
        
        -    <title>{{ .name }}: {{ .path }} ({{ .ref }})</title>

      
        
        5
        +    <title>{{ .RepoName }}: {{ .P.Path }} ({{ .P.Ref }})</title>

      
        6
        6
           </head>

      
        7
        7
           <body>

      
        8
        8
             {{ template "repo_header" . }}

      
        9
        9
             <main>

      
        10
        
        -      <p>{{ .path }} (<a class="muted" href="?raw=true">view raw</a>)</p>

      
        
        10
        +      <p>{{ .P.Path }} (<a class="muted" href="?raw=true">view raw</a>)</p>

      
        11
        11
               <div class="file-wrapper">

      
        12
        
        -        {{ if .is_image }}

      
        
        12
        +        {{ if .P.IsImage }}

      
        13
        13
                 <div class="image-viewer">

      
        14
        
        -          <p>{{.mime_type}} • {{.size}} bytes</p>

      
        15
        
        -          <img src="?raw=true" alt="{{- .path -}}">

      
        
        14
        +          <p>{{ .P.Mime }} • {{ .P.Size }} bytes</p>

      
        
        15
        +          <img src="?raw=true" alt="{{- .P.Path -}}">

      
        16
        16
                 </div>

      
        17
        
        -        {{ else if .is_binary }}

      
        
        17
        +        {{ else if .P.IsBinary }}

      
        18
        18
                 <div class="binary-viewer">

      
        19
        
        -          <p>Binary file ({{.mime_type}})</p>

      
        20
        
        -          <p>Size: {{.size}} bytes</p>

      
        
        19
        +          <p>Binary file ({{ .P.Mime }})</p>

      
        
        20
        +          <p>Size: {{ .P.Size }} bytes</p>

      
        21
        21
                   <a class="link" href="?raw=true" download>[ Download ]</a>

      
        22
        22
                 </div>

      
        23
        23
                 {{ else }}

      
        24
        24
                 <table>

      
        25
        
        -          <tbody><tr>

      
        26
        
        -            <td class="line-numbers">

      
        27
        
        -              <pre>{{- range .linecount }}

      
        
        25
        +          <tbody>

      
        
        26
        +            <tr>

      
        
        27
        +              <td class="line-numbers">

      
        
        28
        +<pre>{{- range .P.LineCount }}

      
        28
        29
         <a id="L{{ . }}" href="#L{{ . }}">{{ . }}</a>

      
        29
        30
         {{- end -}}</pre>

      
        30
        
        -            </td>

      
        31
        
        -            <td class="file-content">

      
        32
        
        -              <pre>{{- .content -}}</pre>

      
        33
        
        -            </td>

      
        34
        
        -          </tbody></tr>

      
        
        31
        +              </td>

      
        
        32
        +              <td class="file-content">

      
        
        33
        +                <pre>{{- .P.Content -}}</pre>

      
        
        34
        +              </td>

      
        
        35
        +            </tr>

      
        
        36
        +          </tbody>

      
        35
        37
                 </table>

      
        36
        38
                 {{ end }}

      
        37
        39
               </div>

      
M web/templates/repo_index.html
···
        3
        3
         <html>

      
        4
        4
           <head>

      
        5
        5
             {{ template "head" . }}

      
        6
        
        -    <title>{{ .name }} &mdash; {{ .meta.Title }}</title>

      
        
        6
        +    <title>{{ .RepoName}} &mdash; {{ .Meta.Title }}</title>

      
        7
        7
           </head>

      
        8
        8
           <body>

      
        9
        9
             {{ template "repo_header" . }}

      
        10
        10
             <main>

      
        11
        
        -      {{ $repo := .name }}

      
        12
        
        -      {{ if .empty }}

      
        
        11
        +      {{ if .P.IsEmpty }}

      
        13
        12
               <h3>Repository is empty</h3>

      
        14
        13
               {{ else }}

      
        15
        14
               <section class="repo-index">

      
        16
        15
                 <div class="repo-index-main">

      
        17
        
        -          {{ range .commits }}

      
        
        16
        +          {{ $repo := .RepoName }}

      
        
        17
        +          {{ range .P.Commits }}

      
        18
        18
                   <div class="box">

      
        19
        19
                     <div>

      
        20
        20
                       <a href="/{{ $repo }}/commit/{{ .Hash }}" class="commit-hash link">{{ .HashShort }}</a>

      ···
        34
        34
         

      
        35
        35
                 <div class="repo-index-side">

      
        36
        36
                   <h2>Clone urls</h2>

      
        37
        
        -          <pre>{{- /* */ -}}

      
        38
        
        -https://{{ .servername }}/{{ .name }}

      
        39
        
        -git@{{ .servername }}:{{ .name }}

      
        40
        
        -{{- /* */ -}}</pre>

      
        41
        
        -

      
        42
        
        -          {{- if .mirrorinfo.isMirror }}

      
        
        37
        +          <pre>https://{{.Meta.Host}}/{{.RepoName}}</pre>

      
        
        38
        +          {{ if .Meta.SSHEnabled }}<pre>git@{{.Meta.Host}}:{{.RepoName}}</pre>{{end}}

      
        
        39
        +          {{- if .P.IsMirror -}}

      
        43
        40
                   <br>

      
        44
        
        -          <h2>Mirror Status</h3>

      
        45
        
        -            <p>

      
        46
        
        -              Last updated {{ humanizeTime .mirrorinfo.lastSync }} from:

      
        47
        
        -              <a href="{{ .mirrorinfo.url }}" target="_blank">{{ .mirrorinfo.url }}</a>

      
        48
        
        -            </p>

      
        49
        
        -            {{- end }}

      
        
        41
        +          <h2>Mirror status</h2>

      
        
        42
        +          <p>

      
        
        43
        +            Last updated {{ humanizeTime .P.MirrorLastSync }} from:

      
        
        44
        +            <a href="{{.P.MirrorURL}}" target="_blank">{{.P.MirrorURL}}</a>

      
        
        45
        +          </p>

      
        
        46
        +          {{- end}}

      
        50
        47
                 </div>

      
        51
        48
               </section>

      
        52
        49
               {{ end }}

      
        53
        50
         

      
        54
        
        -      {{- if .readme }}

      
        55
        
        -      <article class="readme">

      
        56
        
        -        {{- .readme -}}

      
        57
        
        -      </article>

      
        
        51
        +      {{- if .P.Readme }}

      
        
        52
        +      <article class="readme">{{- .P.Readme -}}</article>

      
        58
        53
               {{- end -}}

      
        59
        54
             </main>

      
        60
        55
           </body>

      
M web/templates/repo_log.html
···
        1
        1
         {{ define "repo_log" }}

      
        
        2
        +{{ $repo := .RepoName }}

      
        2
        3
         <html>

      
        3
        4
           <head>

      
        4
        5
             {{ template "head" . }}

      
        5
        
        -  <title>{{ .name }}: log</title>

      
        
        6
        +    <title>{{ $repo }}: log</title>

      
        6
        7
           </head>

      
        7
        8
           <body>

      
        8
        9
             {{ template "repo_header" . }}

      
        9
        10
             <main>

      
        10
        
        -      {{ $repo := .name }}

      
        11
        11
               <table class="table log">

      
        12
        12
                 <thead>

      
        13
        13
                   <tr class="nohover">

      ···
        18
        18
                   </tr>

      
        19
        19
                 </thead>

      
        20
        20
                 <tbody>

      
        21
        
        -          {{ range .commits }}

      
        
        21
        +          {{ range .P.Commits }}

      
        22
        22
                   <tr>

      
        23
        23
                     <td class="fill">

      
        24
        24
                       <a href="/{{ $repo }}/commit/{{ .Hash }}">

      
        25
        25
                         {{- if .Message }}{{- commitSummary .Message -}}

      
        26
        26
                         {{- else -}}<span class="muted">Empty message</span>{{- end -}}

      
        27
        
        -             </a>

      
        
        27
        +              </a>

      
        28
        28
                     </td>

      
        29
        29
                     <td class="author nowrap">

      
        30
        30
                       <span class="author-short">

      
M web/templates/repo_refs.html
···
        1
        1
         {{ define "repo_refs" }}

      
        
        2
        +{{ $repo := .RepoName }}

      
        2
        3
         <html>

      
        3
        4
           <head>

      
        4
        5
             {{ template "head" . }}

      
        5
        
        -    <title>{{ .name }}: refs</title>

      
        
        6
        +    <title>{{ $repo }}: refs</title>

      
        6
        7
           </head>

      
        7
        8
           <body>

      
        8
        9
             {{ template "repo_header" . }}

      
        9
        10
             <main>

      
        10
        
        -      {{ $name := .name }}

      
        11
        11
               <h3>branches</h3>

      
        12
        12
               <div class="refs">

      
        13
        
        -      {{ range .branches }}

      
        
        13
        +        {{ range .P.Branches }}

      
        14
        14
                 <div>

      
        15
        
        -        <strong>{{ .Name }}</strong>

      
        16
        
        -        <a class="link" href="/{{ $name }}/tree/{{ .Name }}/">browse</a>

      
        17
        
        -        <a class="link" href="/{{ $name }}/log/{{ .Name }}">log</a>

      
        18
        
        -        <a class="link" href="/{{ $name }}/archive/{{ .Name }}">tar.gz</a>

      
        
        15
        +          <strong>{{ .Name }}</strong>

      
        
        16
        +          <a class="link" href="/{{ $repo }}/tree/{{ .Name }}/">browse</a>

      
        
        17
        +          <a class="link" href="/{{ $repo }}/log/{{ .Name }}">log</a>

      
        
        18
        +          <a class="link" href="/{{ $repo }}/archive/{{ .Name }}">tar.gz</a>

      
        19
        19
                 </div>

      
        20
        
        -      {{ end }}

      
        
        20
        +        {{ end }}

      
        21
        21
               </div>

      
        22
        
        -      {{ if .tags }}

      
        
        22
        +      {{ if .P.Tags }}

      
        23
        23
               <h3>tags</h3>

      
        24
        24
               <div class="refs">

      
        25
        
        -      {{ range .tags }}

      
        26
        
        -      <div>

      
        27
        
        -      <strong>{{ .Name }}</strong>

      
        28
        
        -      <a class="link" href="/{{ $name }}/tree/{{ .Name }}/">browse</a>

      
        29
        
        -      <a class="link" href="/{{ $name }}/log/{{ .Name }}">log</a>

      
        30
        
        -      <a class="link" href="/{{ $name }}/archive/{{ .Name }}">tar.gz</a>

      
        31
        
        -      {{ if .Message }}

      
        32
        
        -      <pre>{{ .Message }}</pre>

      
        33
        
        -      </div>

      
        34
        
        -      {{ end }}

      
        35
        
        -      {{ end }}

      
        
        25
        +        {{ range .P.Tags }}

      
        
        26
        +        <div>

      
        
        27
        +          <strong>{{ .Name }}</strong>

      
        
        28
        +          <a class="link" href="/{{ $repo }}/tree/{{ .Name }}/">browse</a>

      
        
        29
        +          <a class="link" href="/{{ $repo }}/log/{{ .Name }}">log</a>

      
        
        30
        +          <a class="link" href="/{{ $repo }}/archive/{{ .Name }}">tar.gz</a>

      
        
        31
        +          {{ if .Message }}

      
        
        32
        +          <details>

      
        
        33
        +            <summary>message</summary>

      
        
        34
        +            <pre>{{ .Message }}</pre>

      
        
        35
        +          </details>

      
        
        36
        +          {{ end }}

      
        
        37
        +        </div>

      
        
        38
        +        {{ end }}

      
        36
        39
               </div>

      
        37
        40
               {{ end }}

      
        38
        41
             </main>

      
M web/templates/repo_tree.html
···
        1
        1
         {{ define "repo_tree" }}

      
        
        2
        +{{ $name := .RepoName }}

      
        
        3
        +{{ $ref := .P.Ref }}

      
        2
        4
         <html>

      
        3
        5
           <head>

      
        4
        6
             {{ template "head" . }}

      
        5
        
        -    <title>{{ .name }}: tree ({{ .ref }})</title>

      
        
        7
        +    <title>{{ $name }}: tree ({{ $ref }})</title>

      
        6
        8
           </head>

      
        7
        9
           <body>

      
        8
        10
             {{ template "repo_header" . }}

      
        9
        11
             <main>

      
        10
        
        -      {{ $repo := .name }}

      
        11
        
        -      {{ $ref := .ref }}

      
        12
        
        -      {{ $parent := .parent }}

      
        
        12
        +      {{ $parent := .P.ParentPath }}

      
        13
        13
         

      
        14
        14
               <table class="table tree">

      
        15
        15
                 <thead>

      ···
        24
        24
                   <tr>

      
        25
        25
                     <td class="mode nowrap"></td>

      
        26
        26
                     <td class="size nowrap"></td>

      
        27
        
        -            <td class="fill"><a href="/{{ $repo }}/tree/{{ $ref }}/{{ .dotdot }}">..</a></td>

      
        
        27
        +            <td class="fill"><a href="/{{ $name }}/tree/{{ $ref }}/{{ .P.DotDot }}">..</a></td>

      
        28
        28
                   </tr>

      
        29
        29
                   {{ end }}

      
        30
        30
         

      
        31
        
        -          {{ range .files }}

      
        
        31
        +          {{ range .P.Tree }}

      
        32
        32
                   {{ if not .IsFile }}

      
        33
        33
                   <tr>

      
        34
        34
                     <td class="mode nowrap">{{ .Mode }}</td>

      
        35
        35
                     <td class="size nowrap">{{ .Size }}</td>

      
        36
        36
                     <td class="fill">

      
        37
        37
                       {{ if $parent }}

      
        38
        
        -              <a href="/{{ $repo }}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a>

      
        
        38
        +              <a href="/{{ $name}}/tree/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}/</a>

      
        39
        39
                       {{ else }}

      
        40
        
        -              <a href="/{{ $repo }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a>

      
        
        40
        +              <a href="/{{ $name }}/tree/{{ $ref }}/{{ .Name }}">{{ .Name }}/</a>

      
        41
        41
                       {{ end }}

      
        42
        42
                     </td>

      
        43
        43
                   </tr>

      
        44
        44
                   {{ end }}

      
        45
        45
                   {{ end }}

      
        46
        46
         

      
        47
        
        -          {{ range .files }}

      
        
        47
        +          {{ range .P.Tree }}

      
        48
        48
                   {{ if .IsFile }}

      
        49
        49
                   <tr>

      
        50
        50
                     <td class="mode nowrap">{{ .Mode }}</td>

      
        51
        51
                     <td class="size nowrap">{{ .Size }}</td>

      
        52
        52
                     <td class="fill">

      
        53
        53
                       {{ if $parent }}

      
        54
        
        -              <a href="/{{ $repo }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a>

      
        
        54
        +              <a href="/{{ $name }}/blob/{{ $ref }}/{{ $parent }}/{{ .Name }}">{{ .Name }}</a>

      
        55
        55
                       {{ else }}

      
        56
        
        -              <a href="/{{ $repo }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a>

      
        
        56
        +              <a href="/{{ $name }}/blob/{{ $ref }}/{{ .Name }}">{{ .Name }}</a>

      
        57
        57
                       {{ end }}

      
        58
        58
                     </td>

      
        59
        59
                   </tr>

      ···
        63
        63
               </table>

      
        64
        64
         

      
        65
        65
               <article>

      
        66
        
        -        <pre>

      
        67
        
        -          {{- if .readme }}{{ .readme }}{{- end -}}

      
        68
        
        -        </pre>

      
        
        66
        +        <pre>{{- if .P.Readme }}{{ .P.Readme }}{{- end -}}</pre>

      
        69
        67
               </article>

      
        70
        68
             </main>

      
        71
        69
           </body>