forked from tangled.org/core
this repo has no description

knotserver/git: cache just the commit hash and time

This should help alleviate the memory leakyness that was exhibited when
we stored the entire object.Commit in memory.

Changed files
+40 -17
appview
pages
templates
knotserver
git
types
+2 -2
appview/pages/templates/repo/index.html
···
</a>
<time class="text-xs text-gray-500"
-
>{{ timeFmt .LastCommit.Author.When }}</time
+
>{{ timeFmt .LastCommit.When }}</time
>
</div>
</div>
···
</a>
<time class="text-xs text-gray-500"
-
>{{ timeFmt .LastCommit.Author.When }}</time
+
>{{ timeFmt .LastCommit.When }}</time
>
</div>
</div>
+2 -2
appview/pages/templates/repo/tree.html
···
<i class="w-3 h-3 fill-current" data-lucide="folder"></i>{{ .Name }}
</div>
</a>
-
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.Author.When }}</time>
+
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.When }}</time>
</div>
</div>
{{ end }}
···
<i class="w-3 h-3" data-lucide="file"></i>{{ .Name }}
</div>
</a>
-
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.Author.When }}</time>
+
<time class="text-xs text-gray-500">{{ timeFmt .LastCommit.When }}</time>
</div>
</div>
{{ end }}
+26 -11
knotserver/git/git.go
···
"os/exec"
"path"
"sort"
+
"strconv"
"strings"
"sync"
"time"
···
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/plumbing"
"github.com/go-git/go-git/v5/plumbing/object"
+
"github.com/sotangled/tangled/types"
)
var (
···
return nil
}
-
func (g *GitRepo) LastCommitForPath(path string) (*object.Commit, error) {
+
func (g *GitRepo) LastCommitForPath(path string) (*types.LastCommitInfo, error) {
cacheKey := fmt.Sprintf("%s:%s", g.h.String(), path)
cacheMu.RLock()
-
if commit, found := commitCache.Get(cacheKey); found {
+
if commitInfo, found := commitCache.Get(cacheKey); found {
cacheMu.RUnlock()
-
return commit.(*object.Commit), nil
+
return commitInfo.(*types.LastCommitInfo), nil
}
cacheMu.RUnlock()
-
cmd := exec.Command("git", "-C", g.path, "log", "-1", "--format=%H", "--", path)
+
cmd := exec.Command("git", "-C", g.path, "log", "-1", "--format=%H %ct", "--", path)
var out bytes.Buffer
cmd.Stdout = &out
···
return nil, fmt.Errorf("failed to get commit hash: %w", err)
}
-
commitHash := strings.TrimSpace(out.String())
-
if commitHash == "" {
+
output := strings.TrimSpace(out.String())
+
if output == "" {
return nil, fmt.Errorf("no commits found for path: %s", path)
}
+
parts := strings.SplitN(output, " ", 2)
+
if len(parts) < 2 {
+
return nil, fmt.Errorf("unexpected commit log format")
+
}
+
+
commitHash := parts[0]
+
commitTimeUnix, err := strconv.ParseInt(parts[1], 10, 64)
+
if err != nil {
+
return nil, fmt.Errorf("parsing commit time: %w", err)
+
}
+
commitTime := time.Unix(commitTimeUnix, 0)
+
hash := plumbing.NewHash(commitHash)
-
commit, err := g.r.CommitObject(hash)
-
if err != nil {
-
return nil, err
+
commitInfo := &types.LastCommitInfo{
+
Hash: hash,
+
Message: "",
+
When: commitTime,
}
cacheMu.Lock()
-
commitCache.Set(cacheKey, commit, 1)
+
commitCache.Set(cacheKey, commitInfo, 1)
cacheMu.Unlock()
-
return commit, nil
+
return commitInfo, nil
}
func newInfoWrapper(
+10 -2
types/tree.go
···
package types
import (
-
"github.com/go-git/go-git/v5/plumbing/object"
+
"time"
+
+
"github.com/go-git/go-git/v5/plumbing"
)
// A nicer git tree representation.
···
IsFile bool `json:"is_file"`
IsSubtree bool `json:"is_subtree"`
-
LastCommit *object.Commit `json:"last_commit,omitempty"`
+
LastCommit *LastCommitInfo `json:"last_commit,omitempty"`
+
}
+
+
type LastCommitInfo struct {
+
Hash plumbing.Hash
+
Message string
+
When time.Time
}