cerrado @ 27400b0fce5d4ef3b7fd5ef4d25bac8f00754e33

feat: Add wrapper for commit

Add a wrapper to the commit log that also contains possible reference.
This will be useful once to later display the reference in the commit
log.
  1diff --git a/Makefile b/Makefile
  2index 80aaf2b8a9c0462465409b4d790f3da595ac6812..d214a85865fc83d292df4c6d01848387a1023f50 100644
  3--- a/Makefile
  4+++ b/Makefile
  5@@ -33,7 +33,7 @@ sass: $(OUTPUT_CSS)
  6 
  7 $(OUTPUT_CSS): $(SASS_FILES)
  8 	@mkdir -p $(CSS_DIR)
  9-	sassc $(SASS_DIR)/main.scss $(OUTPUT_CSS)
 10+	sassc --style compressed $(SASS_DIR)/main.scss $(OUTPUT_CSS)
 11 
 12 tmpl: $(GO_TEMPLATES_FILES)
 13 
 14diff --git a/pkg/git/git.go b/pkg/git/git.go
 15index b33afa7bf1f8a453ddc4d2da48273b199f821b96..9e7f9c9bf684606b26bc3a511e7a7c49e400cbbb 100644
 16--- a/pkg/git/git.go
 17+++ b/pkg/git/git.go
 18@@ -32,6 +32,10 @@ 	TagReference struct {
 19 		ref *plumbing.Reference
 20 		tag *object.Tag
 21 	}
 22+	CommitReference struct {
 23+		commit *object.Commit
 24+		ref    *plumbing.Reference
 25+	}
 26 	infoWrapper struct {
 27 		name    string
 28 		size    int64
 29@@ -81,7 +85,7 @@ func (g *GitRepository) Path() string {
 30 	return g.path
 31 }
 32 
 33-func (g *GitRepository) LastCommit() (*object.Commit, error) {
 34+func (g *GitRepository) LastCommit() (*CommitReference, error) {
 35 	err := g.validateRef()
 36 	if err != nil {
 37 		return nil, err
 38@@ -91,10 +95,27 @@ 	c, err := g.repository.CommitObject(g.ref)
 39 	if err != nil {
 40 		return nil, err
 41 	}
 42-	return c, nil
 43+
 44+	iter, err := g.repository.Tags()
 45+	if err != nil {
 46+		return nil, err
 47+	}
 48+
 49+	commitRef := &CommitReference{commit: c}
 50+	if err := iter.ForEach(func(ref *plumbing.Reference) error {
 51+		if ref.Hash() != c.Hash {
 52+			return nil
 53+		}
 54+		commitRef.ref = ref
 55+		return nil
 56+	}); err != nil {
 57+		return nil, err
 58+	}
 59+
 60+	return commitRef, nil
 61 }
 62 
 63-func (g *GitRepository) Commits(count int, from string) ([]*object.Commit, *object.Commit, error) {
 64+func (g *GitRepository) Commits(count int, from string) ([]*CommitReference, *object.Commit, error) {
 65 	err := g.validateRef()
 66 	if err != nil {
 67 		return nil, nil, err
 68@@ -115,7 +136,7 @@ 	if err != nil {
 69 		return nil, nil, fmt.Errorf("commits from ref: %w", err)
 70 	}
 71 
 72-	commits := []*object.Commit{}
 73+	commitRefs := []*CommitReference{}
 74 	var next *object.Commit
 75 
 76 	// iterate one more item so we can fetch the next commit
 77@@ -129,11 +150,29 @@ 		}
 78 		if x == count {
 79 			next = c
 80 		} else {
 81-			commits = append(commits, c)
 82+			commitRefs = append(commitRefs, &CommitReference{commit: c})
 83+		}
 84+	}
 85+
 86+	// new we fetch for possible tags for each commit
 87+	iter, err := g.repository.Tags()
 88+	if err != nil {
 89+		return nil, nil, err
 90+	}
 91+
 92+	if err := iter.ForEach(func(ref *plumbing.Reference) error {
 93+		for _, c := range commitRefs {
 94+			if c.commit.Hash != ref.Hash() {
 95+				continue
 96+			}
 97+			c.ref = ref
 98 		}
 99+		return nil
100+	}); err != nil {
101+		return nil, nil, err
102 	}
103 
104-	return commits, next, nil
105+	return commitRefs, next, nil
106 }
107 
108 func (g *GitRepository) Head() (*plumbing.Reference, error) {
109@@ -452,6 +491,10 @@ 	if t.tag != nil {
110 		return t.tag.Message
111 	}
112 	return ""
113+}
114+
115+func (c *CommitReference) Commit() *object.Commit {
116+	return c.commit
117 }
118 
119 func (self *tagList) Len() int {
120diff --git a/pkg/handler/git/handler.go b/pkg/handler/git/handler.go
121index 80f7de6f1b36030c4d8f4325d523da0e0555e9fd..33adc8d2fba2f83716533128590f7a3398e95f49 100644
122--- a/pkg/handler/git/handler.go
123+++ b/pkg/handler/git/handler.go
124@@ -384,7 +384,7 @@ 	gitList := &templates.GitItemPage{
125 		Name: name,
126 		Ref:  ref,
127 		GitItemBase: &templates.GitItemCommitPage{
128-			Commit: commit,
129+			Commit: commit.Commit(),
130 			Diff:   code.Bytes(),
131 		},
132 	}
133@@ -425,11 +425,11 @@ 			return repos[i].Name > repos[j].Name
134 		})
135 	case config.LastCommitAsc:
136 		sort.Slice(repos, func(i, j int) bool {
137-			return repos[i].LastCommit.Committer.When.Before(repos[j].LastCommit.Committer.When)
138+			return repos[i].LastCommit.Commit().Committer.When.Before(repos[j].LastCommit.Commit().Committer.When)
139 		})
140 	case config.LastCommitDesc:
141 		sort.Slice(repos, func(i, j int) bool {
142-			return repos[i].LastCommit.Committer.When.After(repos[j].LastCommit.Committer.When)
143+			return repos[i].LastCommit.Commit().Committer.When.After(repos[j].LastCommit.Commit().Committer.When)
144 		})
145 	}
146 
147diff --git a/pkg/service/git.go b/pkg/service/git.go
148index 773d335d0d1694bf104f94455ccc6943dce9b07f..8642b5b12a356548b60ec831e1463d93b5dc75b2 100644
149--- a/pkg/service/git.go
150+++ b/pkg/service/git.go
151@@ -18,7 +18,7 @@ 	Repository struct {
152 		Name        string
153 		Description string
154 		Public      bool
155-		LastCommit  *object.Commit
156+		LastCommit  *git.CommitReference
157 		Ref         string
158 	}
159 
160@@ -81,7 +81,7 @@
161 	return repos, nil
162 }
163 
164-func (g *GitService) ListCommits(name, ref, from string, count int) ([]*object.Commit, *object.Commit, error) {
165+func (g *GitService) ListCommits(name, ref, from string, count int) ([]*git.CommitReference, *object.Commit, error) {
166 	r := g.configRepo.GetByName(name)
167 	if r == nil {
168 		return nil, nil, ErrRepositoryNotFound
169@@ -99,7 +99,7 @@ 	}
170 	return repo.Commits(count, from)
171 }
172 
173-func (g *GitService) LastCommit(name, ref string) (*object.Commit, error) {
174+func (g *GitService) LastCommit(name, ref string) (*git.CommitReference, error) {
175 	r := g.configRepo.GetByName(name)
176 	if r == nil {
177 		return nil, ErrRepositoryNotFound
178diff --git a/pkg/u/list.go b/pkg/u/list.go
179index 835ecd289214a9c5a4f30d249c39ee70e957e4ab..1cffbd5f677a6d7f47e5e7a2476656e3c8bdb8d3 100644
180--- a/pkg/u/list.go
181+++ b/pkg/u/list.go
182@@ -12,6 +12,14 @@
183 	return result
184 }
185 
186+func Map[T any, V any](a []T, f func(T) V) []V {
187+	result := make([]V, len(a))
188+	for i, v := range a {
189+		result[i] = f(v)
190+	}
191+	return result
192+}
193+
194 func First[T any](v []T) (T, bool) {
195 	if len(v) == 0 {
196 		var zero T
197diff --git a/templates/gititemlog.qtpl b/templates/gititemlog.qtpl
198index b0c8cec1f2ee8ea9f8cae4dfca45e51e12b1c51e..93efb24c6d716454864985c84523db4ffabd7556 100644
199--- a/templates/gititemlog.qtpl
200+++ b/templates/gititemlog.qtpl
201@@ -1,8 +1,9 @@
202+{% import "git.gabrielgio.me/cerrado/pkg/git" %}
203 {% import "github.com/go-git/go-git/v5/plumbing/object" %}
204 
205 {% code
206 type GitItemLogPage struct {
207-    Commits []*object.Commit
208+    Commits []*git.CommitReference
209     Next *object.Commit
210 }
211 %}
212@@ -12,7 +13,7 @@
213 {% func (g *GitItemLogPage) GitContent(name, ref string) %}
214 <div class="event-list">
215   {% for _, c := range g.Commits %}
216-  {%= Commit(name, c, false) %}
217+  {%= Commit(name, c.Commit(), false) %}
218   {% endfor %}
219   {% if g.Next != nil %}
220   <a href="/{%s name %}/log/{%s ref %}/?from={%s g.Next.Hash.String() %}"  class="btn btn-primary">Next</a>
221diff --git a/templates/gititemlog.qtpl.go b/templates/gititemlog.qtpl.go
222index 719b71f9bb4f74125415288c3438eca26a55624c..05950ed0c7d1a33d204b17fced89a60ff5381892 100644
223--- a/templates/gititemlog.qtpl.go
224+++ b/templates/gititemlog.qtpl.go
225@@ -5,131 +5,134 @@ //line templates/gititemlog.qtpl:1
226 package templates
227 
228 //line templates/gititemlog.qtpl:1
229+import "git.gabrielgio.me/cerrado/pkg/git"
230+
231+//line templates/gititemlog.qtpl:2
232 import "github.com/go-git/go-git/v5/plumbing/object"
233 
234-//line templates/gititemlog.qtpl:3
235+//line templates/gititemlog.qtpl:4
236 import (
237 	qtio422016 "io"
238 
239 	qt422016 "github.com/valyala/quicktemplate"
240 )
241 
242-//line templates/gititemlog.qtpl:3
243+//line templates/gititemlog.qtpl:4
244 var (
245 	_ = qtio422016.Copy
246 	_ = qt422016.AcquireByteBuffer
247 )
248 
249-//line templates/gititemlog.qtpl:4
250+//line templates/gititemlog.qtpl:5
251 type GitItemLogPage struct {
252-	Commits []*object.Commit
253+	Commits []*git.CommitReference
254 	Next    *object.Commit
255 }
256 
257-//line templates/gititemlog.qtpl:10
258+//line templates/gititemlog.qtpl:11
259 func (g *GitItemLogPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) {
260-//line templates/gititemlog.qtpl:10
261+//line templates/gititemlog.qtpl:11
262 	StreamGitItemNav(qw422016, name, ref, Log)
263-//line templates/gititemlog.qtpl:10
264+//line templates/gititemlog.qtpl:11
265 }
266 
267-//line templates/gititemlog.qtpl:10
268+//line templates/gititemlog.qtpl:11
269 func (g *GitItemLogPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) {
270-//line templates/gititemlog.qtpl:10
271+//line templates/gititemlog.qtpl:11
272 	qw422016 := qt422016.AcquireWriter(qq422016)
273-//line templates/gititemlog.qtpl:10
274+//line templates/gititemlog.qtpl:11
275 	g.StreamNav(qw422016, name, ref)
276-//line templates/gititemlog.qtpl:10
277+//line templates/gititemlog.qtpl:11
278 	qt422016.ReleaseWriter(qw422016)
279-//line templates/gititemlog.qtpl:10
280+//line templates/gititemlog.qtpl:11
281 }
282 
283-//line templates/gititemlog.qtpl:10
284+//line templates/gititemlog.qtpl:11
285 func (g *GitItemLogPage) Nav(name, ref string) string {
286-//line templates/gititemlog.qtpl:10
287+//line templates/gititemlog.qtpl:11
288 	qb422016 := qt422016.AcquireByteBuffer()
289-//line templates/gititemlog.qtpl:10
290+//line templates/gititemlog.qtpl:11
291 	g.WriteNav(qb422016, name, ref)
292-//line templates/gititemlog.qtpl:10
293+//line templates/gititemlog.qtpl:11
294 	qs422016 := string(qb422016.B)
295-//line templates/gititemlog.qtpl:10
296+//line templates/gititemlog.qtpl:11
297 	qt422016.ReleaseByteBuffer(qb422016)
298-//line templates/gititemlog.qtpl:10
299+//line templates/gititemlog.qtpl:11
300 	return qs422016
301-//line templates/gititemlog.qtpl:10
302+//line templates/gititemlog.qtpl:11
303 }
304 
305-//line templates/gititemlog.qtpl:12
306+//line templates/gititemlog.qtpl:13
307 func (g *GitItemLogPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
308-//line templates/gititemlog.qtpl:12
309+//line templates/gititemlog.qtpl:13
310 	qw422016.N().S(`
311 <div class="event-list">
312   `)
313-//line templates/gititemlog.qtpl:14
314+//line templates/gititemlog.qtpl:15
315 	for _, c := range g.Commits {
316-//line templates/gititemlog.qtpl:14
317+//line templates/gititemlog.qtpl:15
318 		qw422016.N().S(`
319   `)
320-//line templates/gititemlog.qtpl:15
321-		StreamCommit(qw422016, name, c, false)
322-//line templates/gititemlog.qtpl:15
323+//line templates/gititemlog.qtpl:16
324+		StreamCommit(qw422016, name, c.Commit(), false)
325+//line templates/gititemlog.qtpl:16
326 		qw422016.N().S(`
327   `)
328-//line templates/gititemlog.qtpl:16
329+//line templates/gititemlog.qtpl:17
330 	}
331-//line templates/gititemlog.qtpl:16
332+//line templates/gititemlog.qtpl:17
333 	qw422016.N().S(`
334   `)
335-//line templates/gititemlog.qtpl:17
336+//line templates/gititemlog.qtpl:18
337 	if g.Next != nil {
338-//line templates/gititemlog.qtpl:17
339+//line templates/gititemlog.qtpl:18
340 		qw422016.N().S(`
341   <a href="/`)
342-//line templates/gititemlog.qtpl:18
343+//line templates/gititemlog.qtpl:19
344 		qw422016.E().S(name)
345-//line templates/gititemlog.qtpl:18
346+//line templates/gititemlog.qtpl:19
347 		qw422016.N().S(`/log/`)
348-//line templates/gititemlog.qtpl:18
349+//line templates/gititemlog.qtpl:19
350 		qw422016.E().S(ref)
351-//line templates/gititemlog.qtpl:18
352+//line templates/gititemlog.qtpl:19
353 		qw422016.N().S(`/?from=`)
354-//line templates/gititemlog.qtpl:18
355+//line templates/gititemlog.qtpl:19
356 		qw422016.E().S(g.Next.Hash.String())
357-//line templates/gititemlog.qtpl:18
358+//line templates/gititemlog.qtpl:19
359 		qw422016.N().S(`"  class="btn btn-primary">Next</a>
360   `)
361-//line templates/gititemlog.qtpl:19
362+//line templates/gititemlog.qtpl:20
363 	}
364-//line templates/gititemlog.qtpl:19
365+//line templates/gititemlog.qtpl:20
366 	qw422016.N().S(`
367 
368 </div>
369 `)
370-//line templates/gititemlog.qtpl:22
371+//line templates/gititemlog.qtpl:23
372 }
373 
374-//line templates/gititemlog.qtpl:22
375+//line templates/gititemlog.qtpl:23
376 func (g *GitItemLogPage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) {
377-//line templates/gititemlog.qtpl:22
378+//line templates/gititemlog.qtpl:23
379 	qw422016 := qt422016.AcquireWriter(qq422016)
380-//line templates/gititemlog.qtpl:22
381+//line templates/gititemlog.qtpl:23
382 	g.StreamGitContent(qw422016, name, ref)
383-//line templates/gititemlog.qtpl:22
384+//line templates/gititemlog.qtpl:23
385 	qt422016.ReleaseWriter(qw422016)
386-//line templates/gititemlog.qtpl:22
387+//line templates/gititemlog.qtpl:23
388 }
389 
390-//line templates/gititemlog.qtpl:22
391+//line templates/gititemlog.qtpl:23
392 func (g *GitItemLogPage) GitContent(name, ref string) string {
393-//line templates/gititemlog.qtpl:22
394+//line templates/gititemlog.qtpl:23
395 	qb422016 := qt422016.AcquireByteBuffer()
396-//line templates/gititemlog.qtpl:22
397+//line templates/gititemlog.qtpl:23
398 	g.WriteGitContent(qb422016, name, ref)
399-//line templates/gititemlog.qtpl:22
400+//line templates/gititemlog.qtpl:23
401 	qs422016 := string(qb422016.B)
402-//line templates/gititemlog.qtpl:22
403+//line templates/gititemlog.qtpl:23
404 	qt422016.ReleaseByteBuffer(qb422016)
405-//line templates/gititemlog.qtpl:22
406+//line templates/gititemlog.qtpl:23
407 	return qs422016
408-//line templates/gititemlog.qtpl:22
409+//line templates/gititemlog.qtpl:23
410 }
411diff --git a/templates/gititemsummary.qtpl b/templates/gititemsummary.qtpl
412index f2de5bed534fddcf8bd529a36b06b9e2d1f15755..5d0768026b0ff97fd293904dbdffb9f449fb3fa5 100644
413--- a/templates/gititemsummary.qtpl
414+++ b/templates/gititemsummary.qtpl
415@@ -1,12 +1,11 @@
416 {% import "github.com/go-git/go-git/v5/plumbing" %}
417-{% import "github.com/go-git/go-git/v5/plumbing/object" %}
418 {% import "git.gabrielgio.me/cerrado/pkg/git" %}
419 
420 {% code
421 type GitItemSummaryPage struct {
422     Tags []*git.TagReference
423     Branches []*plumbing.Reference
424-    Commits []*object.Commit
425+    Commits []*git.CommitReference
426 }
427 %}
428 
429@@ -39,7 +38,7 @@ </div>
430 <div class="row">
431   <div class="event-list">
432     {% for _, c := range g.Commits %}
433-    {%= Commit(name, c, false) %}
434+    {%= Commit(name, c.Commit(), false) %}
435     {% endfor %}
436   </div>
437 </div>
438diff --git a/templates/gititemsummary.qtpl.go b/templates/gititemsummary.qtpl.go
439index 41d5b67ee7faf9741b2c745216506dd4fc49fc10..e17ec7c4defe8706cb17a0258a62f0f80fba8d9a 100644
440--- a/templates/gititemsummary.qtpl.go
441+++ b/templates/gititemsummary.qtpl.go
442@@ -8,127 +8,124 @@ //line templates/gititemsummary.qtpl:1
443 import "github.com/go-git/go-git/v5/plumbing"
444 
445 //line templates/gititemsummary.qtpl:2
446-import "github.com/go-git/go-git/v5/plumbing/object"
447-
448-//line templates/gititemsummary.qtpl:3
449 import "git.gabrielgio.me/cerrado/pkg/git"
450 
451-//line templates/gititemsummary.qtpl:5
452+//line templates/gititemsummary.qtpl:4
453 import (
454 	qtio422016 "io"
455 
456 	qt422016 "github.com/valyala/quicktemplate"
457 )
458 
459-//line templates/gititemsummary.qtpl:5
460+//line templates/gititemsummary.qtpl:4
461 var (
462 	_ = qtio422016.Copy
463 	_ = qt422016.AcquireByteBuffer
464 )
465 
466-//line templates/gititemsummary.qtpl:6
467+//line templates/gititemsummary.qtpl:5
468 type GitItemSummaryPage struct {
469 	Tags     []*git.TagReference
470 	Branches []*plumbing.Reference
471-	Commits  []*object.Commit
472+	Commits  []*git.CommitReference
473 }
474 
475-//line templates/gititemsummary.qtpl:13
476+//line templates/gititemsummary.qtpl:12
477 func (g *GitItemSummaryPage) StreamNav(qw422016 *qt422016.Writer, name, ref string) {
478-//line templates/gititemsummary.qtpl:13
479+//line templates/gititemsummary.qtpl:12
480 	StreamGitItemNav(qw422016, name, ref, Summary)
481-//line templates/gititemsummary.qtpl:13
482+//line templates/gititemsummary.qtpl:12
483 }
484 
485-//line templates/gititemsummary.qtpl:13
486+//line templates/gititemsummary.qtpl:12
487 func (g *GitItemSummaryPage) WriteNav(qq422016 qtio422016.Writer, name, ref string) {
488-//line templates/gititemsummary.qtpl:13
489+//line templates/gititemsummary.qtpl:12
490 	qw422016 := qt422016.AcquireWriter(qq422016)
491-//line templates/gititemsummary.qtpl:13
492+//line templates/gititemsummary.qtpl:12
493 	g.StreamNav(qw422016, name, ref)
494-//line templates/gititemsummary.qtpl:13
495+//line templates/gititemsummary.qtpl:12
496 	qt422016.ReleaseWriter(qw422016)
497-//line templates/gititemsummary.qtpl:13
498+//line templates/gititemsummary.qtpl:12
499 }
500 
501-//line templates/gititemsummary.qtpl:13
502+//line templates/gititemsummary.qtpl:12
503 func (g *GitItemSummaryPage) Nav(name, ref string) string {
504-//line templates/gititemsummary.qtpl:13
505+//line templates/gititemsummary.qtpl:12
506 	qb422016 := qt422016.AcquireByteBuffer()
507-//line templates/gititemsummary.qtpl:13
508+//line templates/gititemsummary.qtpl:12
509 	g.WriteNav(qb422016, name, ref)
510-//line templates/gititemsummary.qtpl:13
511+//line templates/gititemsummary.qtpl:12
512 	qs422016 := string(qb422016.B)
513-//line templates/gititemsummary.qtpl:13
514+//line templates/gititemsummary.qtpl:12
515 	qt422016.ReleaseByteBuffer(qb422016)
516-//line templates/gititemsummary.qtpl:13
517+//line templates/gititemsummary.qtpl:12
518 	return qs422016
519-//line templates/gititemsummary.qtpl:13
520+//line templates/gititemsummary.qtpl:12
521 }
522 
523-//line templates/gititemsummary.qtpl:15
524+//line templates/gititemsummary.qtpl:14
525 func (g *GitItemSummaryPage) StreamGitContent(qw422016 *qt422016.Writer, name, ref string) {
526-//line templates/gititemsummary.qtpl:15
527+//line templates/gititemsummary.qtpl:14
528 	qw422016.N().S(`
529 <div class="row">
530   <div class="col-md-8">
531     `)
532-//line templates/gititemsummary.qtpl:18
533+//line templates/gititemsummary.qtpl:17
534 	StreamListTags(qw422016, name, g.Tags)
535-//line templates/gititemsummary.qtpl:18
536+//line templates/gititemsummary.qtpl:17
537 	qw422016.N().S(`
538   </div>
539   <div class="col-md-4">
540     <div class="event-list">
541       `)
542-//line templates/gititemsummary.qtpl:22
543+//line templates/gititemsummary.qtpl:21
544 	for _, b := range g.Branches {
545-//line templates/gititemsummary.qtpl:22
546+//line templates/gititemsummary.qtpl:21
547 		qw422016.N().S(`
548       <div class="row event">
549           <div class="col-4">
550            `)
551-//line templates/gititemsummary.qtpl:25
552+//line templates/gititemsummary.qtpl:24
553 		qw422016.E().S(b.Name().Short())
554-//line templates/gititemsummary.qtpl:25
555+//line templates/gititemsummary.qtpl:24
556 		qw422016.N().S(`
557           </div>
558           <div class="col-8">
559             <div class="float-end">
560               <a href="/`)
561+//line templates/gititemsummary.qtpl:28
562+		qw422016.E().S(name)
563+//line templates/gititemsummary.qtpl:28
564+		qw422016.N().S(`/archive/`)
565+//line templates/gititemsummary.qtpl:28
566+		qw422016.E().S(b.Name().Short())
567+//line templates/gititemsummary.qtpl:28
568+		qw422016.N().S(`.tar.gz">tar.gz</a>
569+              <a href="/`)
570 //line templates/gititemsummary.qtpl:29
571 		qw422016.E().S(name)
572 //line templates/gititemsummary.qtpl:29
573-		qw422016.N().S(`/archive/`)
574+		qw422016.N().S(`/tree/`)
575 //line templates/gititemsummary.qtpl:29
576 		qw422016.E().S(b.Name().Short())
577 //line templates/gititemsummary.qtpl:29
578-		qw422016.N().S(`.tar.gz">tar.gz</a>
579+		qw422016.N().S(`/">tree</a>
580               <a href="/`)
581 //line templates/gititemsummary.qtpl:30
582 		qw422016.E().S(name)
583 //line templates/gititemsummary.qtpl:30
584-		qw422016.N().S(`/tree/`)
585+		qw422016.N().S(`/log/`)
586 //line templates/gititemsummary.qtpl:30
587 		qw422016.E().S(b.Name().Short())
588 //line templates/gititemsummary.qtpl:30
589-		qw422016.N().S(`/">tree</a>
590-              <a href="/`)
591-//line templates/gititemsummary.qtpl:31
592-		qw422016.E().S(name)
593-//line templates/gititemsummary.qtpl:31
594-		qw422016.N().S(`/log/`)
595-//line templates/gititemsummary.qtpl:31
596-		qw422016.E().S(b.Name().Short())
597-//line templates/gititemsummary.qtpl:31
598 		qw422016.N().S(`/">log</a>
599             </div>
600           </div>
601       </div>
602       `)
603-//line templates/gititemsummary.qtpl:35
604+//line templates/gititemsummary.qtpl:34
605 	}
606-//line templates/gititemsummary.qtpl:35
607+//line templates/gititemsummary.qtpl:34
608 	qw422016.N().S(`
609     </div>
610   </div>
611@@ -136,48 +133,48 @@ </div>
612 <div class="row">
613   <div class="event-list">
614     `)
615-//line templates/gititemsummary.qtpl:41
616+//line templates/gititemsummary.qtpl:40
617 	for _, c := range g.Commits {
618-//line templates/gititemsummary.qtpl:41
619+//line templates/gititemsummary.qtpl:40
620 		qw422016.N().S(`
621     `)
622-//line templates/gititemsummary.qtpl:42
623-		StreamCommit(qw422016, name, c, false)
624-//line templates/gititemsummary.qtpl:42
625+//line templates/gititemsummary.qtpl:41
626+		StreamCommit(qw422016, name, c.Commit(), false)
627+//line templates/gititemsummary.qtpl:41
628 		qw422016.N().S(`
629     `)
630-//line templates/gititemsummary.qtpl:43
631+//line templates/gititemsummary.qtpl:42
632 	}
633-//line templates/gititemsummary.qtpl:43
634+//line templates/gititemsummary.qtpl:42
635 	qw422016.N().S(`
636   </div>
637 </div>
638 `)
639-//line templates/gititemsummary.qtpl:46
640+//line templates/gititemsummary.qtpl:45
641 }
642 
643-//line templates/gititemsummary.qtpl:46
644+//line templates/gititemsummary.qtpl:45
645 func (g *GitItemSummaryPage) WriteGitContent(qq422016 qtio422016.Writer, name, ref string) {
646-//line templates/gititemsummary.qtpl:46
647+//line templates/gititemsummary.qtpl:45
648 	qw422016 := qt422016.AcquireWriter(qq422016)
649-//line templates/gititemsummary.qtpl:46
650+//line templates/gititemsummary.qtpl:45
651 	g.StreamGitContent(qw422016, name, ref)
652-//line templates/gititemsummary.qtpl:46
653+//line templates/gititemsummary.qtpl:45
654 	qt422016.ReleaseWriter(qw422016)
655-//line templates/gititemsummary.qtpl:46
656+//line templates/gititemsummary.qtpl:45
657 }
658 
659-//line templates/gititemsummary.qtpl:46
660+//line templates/gititemsummary.qtpl:45
661 func (g *GitItemSummaryPage) GitContent(name, ref string) string {
662-//line templates/gititemsummary.qtpl:46
663+//line templates/gititemsummary.qtpl:45
664 	qb422016 := qt422016.AcquireByteBuffer()
665-//line templates/gititemsummary.qtpl:46
666+//line templates/gititemsummary.qtpl:45
667 	g.WriteGitContent(qb422016, name, ref)
668-//line templates/gititemsummary.qtpl:46
669+//line templates/gititemsummary.qtpl:45
670 	qs422016 := string(qb422016.B)
671-//line templates/gititemsummary.qtpl:46
672+//line templates/gititemsummary.qtpl:45
673 	qt422016.ReleaseByteBuffer(qb422016)
674-//line templates/gititemsummary.qtpl:46
675+//line templates/gititemsummary.qtpl:45
676 	return qs422016
677-//line templates/gititemsummary.qtpl:46
678+//line templates/gititemsummary.qtpl:45
679 }
680diff --git a/templates/gitlist.qtpl b/templates/gitlist.qtpl
681index 3cd133fe2d059826d1b97951b70055d76ca70342..e62e68ad78a4c2a91ff0a9f58a2c5db3314e8fcb 100644
682--- a/templates/gitlist.qtpl
683+++ b/templates/gitlist.qtpl
684@@ -41,9 +41,9 @@         </div>
685         </hr>
686         <p>{%s r.Description %}</p>
687         <div class="event-commit row">
688-            <a class="col-xl-2" title="{%s r.LastCommit.Hash.String() %}" href="/{%s r.Name %}/commit/{%s r.LastCommit.Hash.String() %}/">{%s r.LastCommit.Hash.String()[0:8] %}</a>
689-            <a class="col-xl-7"> {%s firstLine(r.LastCommit.Message) %}</a>
690-            <a class="col-xl-3" title="{%s r.LastCommit.Author.When.UTC().Format("2006-01-02 15:04:05")%} UTC">{%s humanize.Time(r.LastCommit.Author.When) %}</a>
691+            <a class="col-xl-2" title="{%s r.LastCommit.Commit().Hash.String() %}" href="/{%s r.Name %}/commit/{%s r.LastCommit.Commit().Hash.String() %}/">{%s r.LastCommit.Commit().Hash.String()[0:8] %}</a>
692+            <a class="col-xl-7"> {%s firstLine(r.LastCommit.Commit().Message) %}</a>
693+            <a class="col-xl-3" title="{%s r.LastCommit.Commit().Author.When.UTC().Format("2006-01-02 15:04:05")%} UTC">{%s humanize.Time(r.LastCommit.Commit().Author.When) %}</a>
694         </div>
695         <p>
696           <a href="/{%s r.Name %}/log/{%s r.Ref %}/">log</a>
697diff --git a/templates/gitlist.qtpl.go b/templates/gitlist.qtpl.go
698index 1c0fdacaddc4cda916d130eca45b24ed96f1190c..d2b28d95e74d28ca643666c8dff8fecf9d05ff13 100644
699--- a/templates/gitlist.qtpl.go
700+++ b/templates/gitlist.qtpl.go
701@@ -156,7 +156,7 @@ 		qw422016.N().S(`</p>
702         <div class="event-commit row">
703             <a class="col-xl-2" title="`)
704 //line templates/gitlist.qtpl:44
705-		qw422016.E().S(r.LastCommit.Hash.String())
706+		qw422016.E().S(r.LastCommit.Commit().Hash.String())
707 //line templates/gitlist.qtpl:44
708 		qw422016.N().S(`" href="/`)
709 //line templates/gitlist.qtpl:44
710@@ -164,25 +164,25 @@ 		qw422016.E().S(r.Name)
711 //line templates/gitlist.qtpl:44
712 		qw422016.N().S(`/commit/`)
713 //line templates/gitlist.qtpl:44
714-		qw422016.E().S(r.LastCommit.Hash.String())
715+		qw422016.E().S(r.LastCommit.Commit().Hash.String())
716 //line templates/gitlist.qtpl:44
717 		qw422016.N().S(`/">`)
718 //line templates/gitlist.qtpl:44
719-		qw422016.E().S(r.LastCommit.Hash.String()[0:8])
720+		qw422016.E().S(r.LastCommit.Commit().Hash.String()[0:8])
721 //line templates/gitlist.qtpl:44
722 		qw422016.N().S(`</a>
723             <a class="col-xl-7"> `)
724 //line templates/gitlist.qtpl:45
725-		qw422016.E().S(firstLine(r.LastCommit.Message))
726+		qw422016.E().S(firstLine(r.LastCommit.Commit().Message))
727 //line templates/gitlist.qtpl:45
728 		qw422016.N().S(`</a>
729             <a class="col-xl-3" title="`)
730 //line templates/gitlist.qtpl:46
731-		qw422016.E().S(r.LastCommit.Author.When.UTC().Format("2006-01-02 15:04:05"))
732+		qw422016.E().S(r.LastCommit.Commit().Author.When.UTC().Format("2006-01-02 15:04:05"))
733 //line templates/gitlist.qtpl:46
734 		qw422016.N().S(` UTC">`)
735 //line templates/gitlist.qtpl:46
736-		qw422016.E().S(humanize.Time(r.LastCommit.Author.When))
737+		qw422016.E().S(humanize.Time(r.LastCommit.Commit().Author.When))
738 //line templates/gitlist.qtpl:46
739 		qw422016.N().S(`</a>
740         </div>