github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/last_commit_cache_nogogit.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 //go:build !gogit 7 8 package git 9 10 import ( 11 "bufio" 12 "context" 13 14 "github.com/gitbundle/modules/log" 15 ) 16 17 // LastCommitCache represents a cache to store last commit 18 type LastCommitCache struct { 19 repoPath string 20 ttl func() int64 21 repo *Repository 22 commitCache map[string]*Commit 23 cache Cache 24 } 25 26 // NewLastCommitCache creates a new last commit cache for repo 27 func NewLastCommitCache(repoPath string, gitRepo *Repository, ttl func() int64, cache Cache) *LastCommitCache { 28 if cache == nil { 29 return nil 30 } 31 return &LastCommitCache{ 32 repoPath: repoPath, 33 repo: gitRepo, 34 commitCache: make(map[string]*Commit), 35 ttl: ttl, 36 cache: cache, 37 } 38 } 39 40 // Get get the last commit information by commit id and entry path 41 func (c *LastCommitCache) Get(ref, entryPath string, wr WriteCloserError, rd *bufio.Reader) (interface{}, error) { 42 v := c.cache.Get(c.getCacheKey(c.repoPath, ref, entryPath)) 43 if vs, ok := v.(string); ok { 44 log.Debug("LastCommitCache hit level 1: [%s:%s:%s]", ref, entryPath, vs) 45 if commit, ok := c.commitCache[vs]; ok { 46 log.Debug("LastCommitCache hit level 2: [%s:%s:%s]", ref, entryPath, vs) 47 return commit, nil 48 } 49 id, err := c.repo.ConvertToSHA1(vs) 50 if err != nil { 51 return nil, err 52 } 53 if _, err := wr.Write([]byte(vs + "\n")); err != nil { 54 return nil, err 55 } 56 commit, err := c.repo.getCommitFromBatchReader(rd, id) 57 if err != nil { 58 return nil, err 59 } 60 c.commitCache[vs] = commit 61 return commit, nil 62 } 63 return nil, nil 64 } 65 66 // CacheCommit will cache the commit from the gitRepository 67 func (c *LastCommitCache) CacheCommit(ctx context.Context, commit *Commit) error { 68 return c.recursiveCache(ctx, commit, &commit.Tree, "", 1) 69 } 70 71 func (c *LastCommitCache) recursiveCache(ctx context.Context, commit *Commit, tree *Tree, treePath string, level int) error { 72 if level == 0 { 73 return nil 74 } 75 76 entries, err := tree.ListEntries() 77 if err != nil { 78 return err 79 } 80 81 entryPaths := make([]string, len(entries)) 82 for i, entry := range entries { 83 entryPaths[i] = entry.Name() 84 } 85 86 _, err = WalkGitLog(ctx, c, commit.repo, commit, treePath, entryPaths...) 87 if err != nil { 88 return err 89 } 90 91 for _, treeEntry := range entries { 92 // entryMap won't contain "" therefore skip this. 93 if treeEntry.IsDir() { 94 subTree, err := tree.SubTree(treeEntry.Name()) 95 if err != nil { 96 return err 97 } 98 if err := c.recursiveCache(ctx, commit, subTree, treeEntry.Name(), level-1); err != nil { 99 return err 100 } 101 } 102 } 103 104 return nil 105 }