Mirror of @tangled.org/core. Running on a Raspberry Pi Zero 2

knotserver/{git,xrpc}: last commit for specific file path

RepoBlob now also includes the last commit for the blob.

Signed-off-by: Anirudh Oppiliappan <anirudh@tangled.org>

authored by anirudh.fi and committed by tangled.org 94340f70 e3285ce3

+61
+36
knotserver/git/last_commit.go
··· 14 14 "github.com/dgraph-io/ristretto" 15 15 "github.com/go-git/go-git/v5/plumbing" 16 16 "github.com/go-git/go-git/v5/plumbing/object" 17 + "tangled.org/core/types" 17 18 ) 18 19 19 20 var ( ··· 185 184 ancestors = append(ancestors, p) 186 185 } 187 186 return ancestors 187 + } 188 + 189 + // GetLastCommitForPath returns the last commit information for a specific file path 190 + func (g *GitRepo) GetLastCommitForPath(ctx context.Context, filePath string) (*types.LastCommitInfo, error) { 191 + c, err := g.r.CommitObject(g.h) 192 + if err != nil { 193 + return nil, fmt.Errorf("commit object: %w", err) 194 + } 195 + 196 + tree, err := c.Tree() 197 + if err != nil { 198 + return nil, fmt.Errorf("file tree: %w", err) 199 + } 200 + 201 + // parent directory for calculateCommitTime 202 + parent := path.Dir(filePath) 203 + if parent == "." { 204 + parent = "" 205 + } 206 + 207 + times, err := g.calculateCommitTimeIn(ctx, tree, parent, 2*time.Second) 208 + if err != nil { 209 + return nil, fmt.Errorf("calculate commit time: %w", err) 210 + } 211 + 212 + commitInfo, ok := times[filePath] 213 + if !ok { 214 + return nil, fmt.Errorf("no commit found for path: %s", filePath) 215 + } 216 + 217 + return &types.LastCommitInfo{ 218 + Hash: commitInfo.hash, 219 + Message: commitInfo.message, 220 + When: commitInfo.when, 221 + }, nil 188 222 }
+25
knotserver/xrpc/repo_blob.go
··· 1 1 package xrpc 2 2 3 3 import ( 4 + "context" 4 5 "crypto/sha256" 5 6 "encoding/base64" 6 7 "fmt" ··· 9 8 "path/filepath" 10 9 "slices" 11 10 "strings" 11 + "time" 12 12 13 13 "tangled.org/core/api/tangled" 14 14 "tangled.org/core/knotserver/git" ··· 142 140 143 141 if mimeType != "" { 144 142 response.MimeType = &mimeType 143 + } 144 + 145 + ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second) 146 + defer cancel() 147 + 148 + lastCommit, err := gr.GetLastCommitForPath(ctx, treePath) 149 + if err == nil && lastCommit != nil { 150 + shortHash := lastCommit.Hash.String()[:8] 151 + response.LastCommit = &tangled.RepoBlob_LastCommit{ 152 + Hash: lastCommit.Hash.String(), 153 + ShortHash: &shortHash, 154 + Message: lastCommit.Message, 155 + When: lastCommit.When.Format(time.RFC3339), 156 + } 157 + 158 + // try to get author information 159 + commit, err := gr.Commit(lastCommit.Hash) 160 + if err == nil { 161 + response.LastCommit.Author = &tangled.RepoBlob_Signature{ 162 + Name: commit.Author.Name, 163 + Email: commit.Author.Email, 164 + } 165 + } 145 166 } 146 167 147 168 writeJson(w, response)