ci/internal/git/repo.go (46 lines of code) (raw):

package git import ( "bufio" "bytes" "context" "fmt" "os/exec" "path/filepath" ) // Repository represents a local Git repository. type Repository struct { dir string } // NewRepository creates a new repository for the given directory path. func NewRepository(dir string) (*Repository, error) { abs, err := filepath.Abs(dir) if err != nil { return nil, fmt.Errorf("getting absolute directory path: %w", err) } return &Repository{dir: abs}, nil } func (r *Repository) Dir() string { return r.dir } // ModifiedFiles return a slice of filenames that were modified since the given commit. func (r *Repository) ModifiedFiles(ctx context.Context, commit string) ([]string, error) { return r.diffNameOnly(ctx, "M", commit) } func (r *Repository) diffNameOnly(ctx context.Context, filter, commit string) ([]string, error) { var files []string out, err := r.execGit(ctx, "diff", "--name-only", "--diff-filter="+filter, commit, "HEAD") if err != nil { return files, fmt.Errorf("running git diff command: %w (output: %s)", err, bytes.TrimSpace(out)) } scanner := bufio.NewScanner(bytes.NewReader(out)) for scanner.Scan() { line := string(bytes.TrimSpace(scanner.Bytes())) if line == "" { continue } files = append(files, filepath.Join(r.dir, line)) } return files, nil } func (r *Repository) execGit(ctx context.Context, arg ...string) ([]byte, error) { cmd := exec.CommandContext(ctx, "git", arg...) cmd.Dir = r.dir return cmd.CombinedOutput() }