package gitcmd import ( "context" "os" "path/filepath" "strings" ) type Repository struct { Path string ctx context.Context } func OpenRepository(ctx context.Context, repoPath string) (*Repository, error) { abs, err := filepath.Abs(repoPath) if err != nil { return nil, err } if _, err := os.Stat(abs); err != nil { return nil, err } if _, err := os.Stat(filepath.Join(abs, "objects")); os.IsNotExist(err) { return nil, os.ErrNotExist } if _, err := os.Stat(filepath.Join(abs, "refs")); os.IsNotExist(err) { return nil, os.ErrNotExist } return &Repository{Path: abs, ctx: ctx}, nil } func (r *Repository) Context() context.Context { return r.ctx } func (r *Repository) WithContext(ctx context.Context) *Repository { return &Repository{Path: r.Path, ctx: ctx} } func (r *Repository) Command(args ...string) *Command { return NewCommand(args...).WithDir(r.Path) } func (r *Repository) IsEmpty() (bool, error) { stdout, _, err := NewCommand("rev-list", "-n", "1", "--all"). WithDir(r.Path). RunStdString(r.ctx) if err != nil { if strings.Contains(err.Error(), "exit status 1") || strings.Contains(err.Error(), "exit status 129") { return true, nil } return false, err } return strings.TrimSpace(stdout) == "", nil } func (r *Repository) DefaultBranch() (string, error) { data, err := os.ReadFile(filepath.Join(r.Path, "HEAD")) if err != nil { return "", err } const prefix = "ref: refs/heads/" line := strings.TrimSpace(string(data)) if after, ok := strings.CutPrefix(line, prefix); ok { return after, nil } return "", nil }