Monorepo for Tangled tangled.org

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

merged opened by anirudh.fi targeting master from icy/xsonzl

RepoBlob now also includes the last commit for the blob.

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

Labels

None yet.

assignee

None yet.

Participants 2
AT URI
at://did:plc:hwevmowznbiukdf6uk5dwrrq/sh.tangled.repo.pull/3mdierjnvhh22
+61
Diff #0
+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 186 } 186 187 return ancestors 187 188 } 189 + 190 + // GetLastCommitForPath returns the last commit information for a specific file path 191 + func (g *GitRepo) GetLastCommitForPath(ctx context.Context, filePath string) (*types.LastCommitInfo, error) { 192 + c, err := g.r.CommitObject(g.h) 193 + if err != nil { 194 + return nil, fmt.Errorf("commit object: %w", err) 195 + } 196 + 197 + tree, err := c.Tree() 198 + if err != nil { 199 + return nil, fmt.Errorf("file tree: %w", err) 200 + } 201 + 202 + // parent directory for calculateCommitTime 203 + parent := path.Dir(filePath) 204 + if parent == "." { 205 + parent = "" 206 + } 207 + 208 + times, err := g.calculateCommitTimeIn(ctx, tree, parent, 2*time.Second) 209 + if err != nil { 210 + return nil, fmt.Errorf("calculate commit time: %w", err) 211 + } 212 + 213 + commitInfo, ok := times[filePath] 214 + if !ok { 215 + return nil, fmt.Errorf("no commit found for path: %s", filePath) 216 + } 217 + 218 + return &types.LastCommitInfo{ 219 + Hash: commitInfo.hash, 220 + Message: commitInfo.message, 221 + When: commitInfo.when, 222 + }, nil 223 + }
+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" ··· 8 9 "path/filepath" 9 10 "slices" 10 11 "strings" 12 + "time" 11 13 12 14 "tangled.org/core/api/tangled" 13 15 "tangled.org/core/knotserver/git" ··· 142 144 response.MimeType = &mimeType 143 145 } 144 146 147 + ctx, cancel := context.WithTimeout(r.Context(), 2*time.Second) 148 + defer cancel() 149 + 150 + lastCommit, err := gr.GetLastCommitForPath(ctx, treePath) 151 + if err == nil && lastCommit != nil { 152 + shortHash := lastCommit.Hash.String()[:8] 153 + response.LastCommit = &tangled.RepoBlob_LastCommit{ 154 + Hash: lastCommit.Hash.String(), 155 + ShortHash: &shortHash, 156 + Message: lastCommit.Message, 157 + When: lastCommit.When.Format(time.RFC3339), 158 + } 159 + 160 + // try to get author information 161 + commit, err := gr.Commit(lastCommit.Hash) 162 + if err == nil { 163 + response.LastCommit.Author = &tangled.RepoBlob_Signature{ 164 + Name: commit.Author.Name, 165 + Email: commit.Author.Email, 166 + } 167 + } 168 + } 169 + 145 170 writeJson(w, response) 146 171 } 147 172

History

1 round 1 comment
sign up or login to add to the discussion
anirudh.fi submitted #0
1 commit
expand
knotserver/{git,xrpc}: last commit for specific file path
2/3 failed, 1/3 success
expand
expand 1 comment

this is just a more specific case of calculateCommitTime (from the same file).

  • the newly introduced function returns the LastCommitInfo for a single file
  • the old function returns a map[string]LastCommitInfo for a list of files

what we can do instead, is extract the core logic for commit-info parsing (that parses the output of g.streamingGitLog), and reuse for both scenarios.

presently, the newly introduced function is slightly inefficient because it runs for the parent dir and then selects the required path.

pull request successfully merged