diff options
| author | mo khan <mo@mokhan.ca> | 2026-01-30 23:42:28 -0700 |
|---|---|---|
| committer | mo khan <mo@mokhan.ca> | 2026-01-30 23:42:28 -0700 |
| commit | 1bbe5e40640b39b7a08e4b9bcf08f7fdbdbb2f0a (patch) | |
| tree | 2e30ddd0cb8ad61059a6d8acd8307fa4f28d9050 /internal/git | |
| parent | bbcd6c6d62f3befb58feddfa16513a5cd4c00473 (diff) | |
refactor: return err instead of panic and use errgroup
Diffstat (limited to 'internal/git')
| -rw-r--r-- | internal/git/git.go | 89 |
1 files changed, 30 insertions, 59 deletions
diff --git a/internal/git/git.go b/internal/git/git.go index 96856c3..41031e4 100644 --- a/internal/git/git.go +++ b/internal/git/git.go @@ -11,14 +11,25 @@ import ( "time" ) -func Branches(repoDir string) ([]Ref, error) { - cmd := exec.Command("git", "for-each-ref", "--format=%(refname:short)", "refs/heads/") +func gitCmd(repoDir string, args ...string) ([]byte, error) { + cmd := exec.Command("git", args...) if repoDir != "" { cmd.Dir = repoDir } out, err := cmd.Output() if err != nil { - return nil, fmt.Errorf("failed to list branches: %w", err) + if ee, ok := err.(*exec.ExitError); ok { + return nil, fmt.Errorf("git %s: %w: %s", args[0], err, ee.Stderr) + } + return nil, err + } + return out, nil +} + +func Branches(repoDir string) ([]Ref, error) { + out, err := gitCmd(repoDir, "for-each-ref", "--format=%(refname:short)", "refs/heads/") + if err != nil { + return nil, err } lines := strings.Split(string(out), "\n") branches := make([]Ref, 0, len(lines)) @@ -33,24 +44,19 @@ func Branches(repoDir string) ([]Ref, error) { func Tags(repoDir string) ([]Tag, error) { format := []string{ - "%(refname:short)", // tag name - "%(creatordate:unix)", // creation date - "%(objectname)", // commit hash for lightweight tags - "%(*objectname)", // peeled object => commit hash + "%(refname:short)", + "%(creatordate:unix)", + "%(objectname)", + "%(*objectname)", } - args := []string{ + out, err := gitCmd(repoDir, "for-each-ref", "--sort=-creatordate", - "--format=" + strings.Join(format, "%00"), + "--format="+strings.Join(format, "%00"), "refs/tags", - } - cmd := exec.Command("git", args...) - if repoDir != "" { - cmd.Dir = repoDir - } - out, err := cmd.Output() + ) if err != nil { - return nil, fmt.Errorf("failed to list tags: %w", err) + return nil, err } lines := strings.Split(strings.TrimSpace(string(out)), "\n") @@ -194,52 +200,22 @@ func BlobContent(ref Ref, path string, repoDir string) ([]byte, bool, error) { if ref.IsEmpty() { ref = NewRef("HEAD") } - // Use `git show ref:path` to get the blob content at that ref - cmd := exec.Command("git", "show", ref.String()+":"+path) - if repoDir != "" { - cmd.Dir = repoDir - } - out, err := cmd.Output() + out, err := gitCmd(repoDir, "show", ref.String()+":"+path) if err != nil { - // include stderr if available - if ee, ok := err.(*exec.ExitError); ok { - return nil, false, fmt.Errorf("git show failed: %v: %s", err, string(ee.Stderr)) - } - return nil, false, fmt.Errorf("git show failed: %w", err) + return nil, false, err } return out, IsBinary(out), nil } func Commits(ref Ref, repoDir string) ([]Commit, error) { - format := []string{ - "%H", // commit hash - "%h", // abbreviated commit hash - "%s", // subject - "%b", // body - "%an", // author name - "%ae", // author email - "%ad", // author date - "%cn", // committer name - "%ce", // committer email - "%cd", // committer date - "%P", // parent hashes - "%D", // ref names without the "(", ")" wrapping. - } - - args := []string{ + format := []string{"%H", "%h", "%s", "%b", "%an", "%ae", "%ad", "%cn", "%ce", "%cd", "%P", "%D"} + out, err := gitCmd(repoDir, "log", "--date=unix", - "--pretty=format:" + strings.Join(format, "\x1F"), - "-z", // Separate the commits with NULs instead of newlines + "--pretty=format:"+strings.Join(format, "\x1F"), + "-z", ref.String(), - } - - cmd := exec.Command("git", args...) - if repoDir != "" { - cmd.Dir = repoDir - } - - out, err := cmd.Output() + ) if err != nil { return nil, err } @@ -347,12 +323,7 @@ func parseRefNames(refNames string) []RefName { } func CommitDiff(hash, repoDir string) (string, error) { - // unified diff without a commit header - cmd := exec.Command("git", "show", "--pretty=format:", "--patch", hash) - if repoDir != "" { - cmd.Dir = repoDir - } - out, err := cmd.Output() + out, err := gitCmd(repoDir, "show", "--pretty=format:", "--patch", hash) if err != nil { return "", err } |
