Files
byre/internal/git/git.go
T

87 lines
1.7 KiB
Go

package git
import (
"fmt"
"os/exec"
"path/filepath"
"strings"
)
type RepoInfo struct {
Root string
DefaultBranch string
Remote string
}
func Inspect(path string) (RepoInfo, error) {
abs, err := filepath.Abs(path)
if err != nil {
return RepoInfo{}, err
}
root, err := run(abs, "rev-parse", "--show-toplevel")
if err != nil {
return RepoInfo{}, err
}
root, err = filepath.EvalSymlinks(root)
if err != nil {
return RepoInfo{}, err
}
abs, err = filepath.EvalSymlinks(abs)
if err != nil {
return RepoInfo{}, err
}
if root != abs {
return RepoInfo{}, fmt.Errorf("%s is inside the repo at %s; register the repo root", abs, root)
}
branch, err := run(root, "symbolic-ref", "--short", "HEAD")
if err != nil {
return RepoInfo{}, err
}
remote, err := run(root, "remote", "get-url", "origin")
if err != nil {
return RepoInfo{}, err
}
return RepoInfo{Root: root, DefaultBranch: branch, Remote: remote}, nil
}
func AddWorktree(repo, path, branch, base string) (string, error) {
sha, err := run(repo, "rev-parse", "--verify", base+"^{commit}")
if err != nil {
return "", err
}
_, err = run(repo, "worktree", "add", "-b", branch, path, sha)
if err != nil {
return "", err
}
return sha, nil
}
func RemoveWorktree(repo, path, branch string) error {
_, err := run(repo, "worktree", "remove", "--force", path)
if err != nil {
return err
}
_, err = run(repo, "branch", "-D", branch)
return err
}
func run(dir string, args ...string) (string, error) {
cmd := exec.Command("git", args...)
cmd.Dir = dir
out, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("git %s: %w: %s", strings.Join(args, " "), err, strings.TrimSpace(string(out)))
}
return strings.TrimSpace(string(out)), nil
}