Monorepo for Tangled tangled.org
2

Configure Feed

Select the types of activity you want to include in your feed.

knotmirror/xrpc: include blob size on `git.getEntry`

Signed-off-by: Seongmin Lee <git@boltless.me>

author
Seongmin Lee
committer
Tangled
date (Jun 19, 2026, 1:24 PM +0300) commit 02270a21 parent 09bd1662 change-id tvvpxpru
+55
+7
knotmirror/xrpc/git_get_entry.go
··· 56 56 writeJson(w, http.StatusNotFound, atclient.ErrorBody{Name: "EntryNotFound", Message: fmt.Sprintf("entry %q not found", path)}) 57 57 return 58 58 } 59 + size, err := gitea.GetBlobSize(ctx, repoPath, entry.Hash) 60 + if err != nil { 61 + l.Error("failed to read blob size", "err", err) 62 + writeJson(w, http.StatusInternalServerError, atclient.ErrorBody{Name: "InternalServerError", Message: "failed to read blob size"}) 63 + return 64 + } 59 65 60 66 var outLastCommit *tangled.GitTempDefs_Commit 61 67 var outSubmodule *tangled.GitTempDefs_Submodule ··· 106 112 Name: entry.Name, 107 113 Mode: entry.Mode.String(), 108 114 Oid: entry.Hash.String(), 115 + Size: size, 109 116 LastCommit: outLastCommit, 110 117 Submodule: outSubmodule, 111 118 })
+38
knotmirror/xrpc/gitea/batch.go
··· 109 109 return entries, nil 110 110 } 111 111 112 + func CatFileBatchCheck(ctx context.Context, repoPath string) (io.WriteCloser, *bufio.Reader, func()) { 113 + batchStdinReader, batchStdinWriter := io.Pipe() 114 + batchStdoutReader, batchStdoutWriter := nio.Pipe(buffer.New(32 * 1024)) 115 + ctx, ctxCancel := context.WithCancel(ctx) 116 + closed := make(chan struct{}) 117 + cancel := func() { 118 + ctxCancel() 119 + _ = batchStdinWriter.Close() 120 + _ = batchStdoutReader.Close() 121 + <-closed 122 + } 123 + 124 + // Ensure cancel is called as soon as the provided context is cancelled 125 + go func() { 126 + <-ctx.Done() 127 + cancel() 128 + }() 129 + 130 + go func() { 131 + stderr := &strings.Builder{} 132 + cmd := exec.CommandContext(ctx, "git", "-C", repoPath, "cat-file", "--batch-check") 133 + cmd.Stdin = batchStdinReader 134 + cmd.Stdout = batchStdoutWriter 135 + cmd.Stderr = stderr 136 + if err := cmd.Run(); err != nil { 137 + _ = batchStdinReader.CloseWithError(fmt.Errorf("%w\n%s", err, stderr.String())) 138 + _ = batchStdoutWriter.CloseWithError(fmt.Errorf("%w\n%s", err, stderr.String())) 139 + } else { 140 + _ = batchStdoutWriter.Close() 141 + _ = batchStdinReader.Close() 142 + } 143 + close(closed) 144 + }() 145 + 146 + batchReader := bufio.NewReaderSize(batchStdoutReader, 32*1024) 147 + return batchStdinWriter, batchReader, cancel 148 + } 149 + 112 150 func CatFileBatch(ctx context.Context, repoPath string) (io.WriteCloser, *bufio.Reader, func()) { 113 151 batchStdinReader, batchStdinWriter := io.Pipe() 114 152 batchStdoutReader, batchStdoutWriter := nio.Pipe(buffer.New(32 * 1024))
+10
knotmirror/xrpc/gitea/blob.go
··· 12 12 "github.com/go-git/go-git/v5/plumbing" 13 13 ) 14 14 15 + func GetBlobSize(ctx context.Context, repoPath string, hash plumbing.Hash) (int64, error) { 16 + wr, rd, cancel := CatFileBatchCheck(ctx, repoPath) 17 + defer cancel() 18 + if _, err := wr.Write([]byte(hash.String() + "\n")); err != nil { 19 + return 0, err 20 + } 21 + _, _, size, err := ReadBatchLine(rd) 22 + return size, err 23 + } 24 + 15 25 // ReadBlob returns blob size and [io.ReadCloser] of that blob. 16 26 func ReadBlob(ctx context.Context, repoPath string, hash plumbing.Hash) (int64, io.ReadCloser, error) { 17 27 wr, rd, cancel := CatFileBatch(ctx, repoPath)