Lightweight and easily self-hostable Git forge. git.poy.ooo
git-forge selfhosting homebrew
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104package git
import ( "fmt" "io" "os" "os/exec" "strconv" "strings"
"github.com/go-git/go-git/v6/plumbing" "github.com/go-git/go-git/v6/plumbing/object")
// returns the tree entry for a file path without loading the blob contents. low RAM usage.func FindFileEntry(tree *object.Tree, path string) (*object.TreeEntry, error) { path = strings.TrimPrefix(path, "/") if path == "" { return nil, fmt.Errorf("git: empty path") }
entry, err := tree.FindEntry(path) if err != nil { return nil, err } if !entry.Mode.IsFile() { return nil, fmt.Errorf("git: %s is not a file", path) }
return entry, nil}
// returns the size in bytes of a blob using git. only reads the object header. low RAM usage.func BlobSize(repoPath string, hash plumbing.Hash) (int64, error) { cmd := exec.Command("git", "-C", repoPath, "cat-file", "-s", hash.String()) out, err := cmd.Output() if err != nil { return 0, fmt.Errorf("git cat-file -s: %w", err) }
size, err := strconv.ParseInt(strings.TrimSpace(string(out)), 10, 64) if err != nil { return 0, fmt.Errorf("git cat-file -s: %w", err) }
return size, nil}
// streams the contents of a blob to w using git. low RAM usage.func StreamBlob(repoPath string, hash plumbing.Hash, w io.Writer) error { cmd := exec.Command("git", "-C", repoPath, "cat-file", "blob", hash.String()) cmd.Stderr = os.Stderr
stdout, err := cmd.StdoutPipe() if err != nil { return fmt.Errorf("git cat-file: %w", err) }
if err := cmd.Start(); err != nil { return fmt.Errorf("git cat-file: %w", err) }
_, err = io.Copy(w, stdout) if err != nil { cmd.Process.Kill() cmd.Wait() return fmt.Errorf("stream blob: %w", err) }
if err := cmd.Wait(); err != nil { return fmt.Errorf("git cat-file: %w", err) }
return nil}
// reads n bytes from the start of a blob. used for mimetypes.func ReadBlobPrefix(repoPath string, hash plumbing.Hash, n int64) ([]byte, error) { cmd := exec.Command("git", "-C", repoPath, "cat-file", "blob", hash.String()) cmd.Stderr = os.Stderr
stdout, err := cmd.StdoutPipe() if err != nil { return nil, fmt.Errorf("git cat-file: %w", err) }
if err := cmd.Start(); err != nil { return nil, fmt.Errorf("git cat-file: %w", err) }
data, err := io.ReadAll(io.LimitReader(stdout, n)) if err != nil { cmd.Process.Kill() cmd.Wait() return nil, fmt.Errorf("read blob prefix: %w", err) }
// for big blobs git may still be writing to the pipe; don't leave it hanging. cmd.Process.Kill() cmd.Wait()
return data, nil}