blob: e2ab030136f243176dc25eb264a488b249038832 [file]
package git
import (
"fmt"
"io"
"os/exec"
"strings"
)
// IsClean checks if the repo in the current directory is clean.
//
// Untracked files are okay, but modified, added, or deleted files are not.
func IsClean() (bool, error) {
cmd := exec.Command("git", "status", "--porcelain")
out, err := cmd.Output()
if err != nil {
return false, fmt.Errorf("git status failed: %v", err)
}
lines := strings.Split(string(out), "\n")
for _, line := range lines {
if line == "" {
continue
}
// Ignore untracked files.
if !strings.HasPrefix(line, "??") {
return false, nil
}
}
return true, nil
}
// ApplyPatches applies a list of patches to the current repo with `git am <paths>`.
//
// The combined output of the command is written to the given writer.
func ApplyPatches(paths []string, writer io.Writer) error {
cmd := exec.Command("git", append([]string{"am"}, paths...)...)
cmd.Stdout = writer
cmd.Stderr = writer
if err := cmd.Run(); err != nil {
return fmt.Errorf("`git am` command failed: %v", err)
}
return nil
}
// Add adds a list of files to the current repo with `git add <files>`.
//
// The combined output of the command is written to the given writer.
func Add(files []string, writer io.Writer) error {
cmd := exec.Command("git", append([]string{"add"}, files...)...)
cmd.Stdout = writer
cmd.Stderr = writer
if err := cmd.Run(); err != nil {
return fmt.Errorf("`git add` command failed: %v", err)
}
return nil
}
// Commit commits changes to the current repo with `git commit <message>`.
//
// The combined output of the command is written to the given writer.
func Commit(message string, writer io.Writer) error {
cmd := exec.Command("git", "commit", "-m", message)
cmd.Stdout = writer
cmd.Stderr = writer
if err := cmd.Run(); err != nil {
return fmt.Errorf("`git commit` command failed: %v", err)
}
return nil
}
// SwitchToNewBranch creates a branch in the current repo and switches to
// it using `git switch -c <branch>`.
//
// The combined output of the command is written to the given writer.
func SwitchToNewBranch(branch string, writer io.Writer) error {
cmd := exec.Command("git", "switch", "-c", branch)
cmd.Stdout = writer
cmd.Stderr = writer
if err := cmd.Run(); err != nil {
return fmt.Errorf("command %s failed: %v", cmd, err)
}
return nil
}
// FindCommitByPattern searches the git log for the provided pattern and
// returns the first commit hash it finds.
func FindCommitByPattern(pattern string) (string, error) {
cmd := exec.Command("git", "log", "-n1", "--format=%H", "--grep", pattern)
out, err := cmd.CombinedOutput()
if err != nil {
return "", fmt.Errorf("command %s failed: %v", cmd, err)
}
return strings.TrimSpace(string(out)), nil
}
// FormatPatch formats a revision range as patches and writes them to the
// provided output directory.
//
// The combined output of the command is written to the given writer.
func FormatPatch(revisionRange, outDir string, writer io.Writer) error {
cmd := exec.Command("git", "format-patch", revisionRange, "-o", outDir)
cmd.Stdout = writer
cmd.Stderr = writer
if err := cmd.Run(); err != nil {
return fmt.Errorf("command %s failed: %v", cmd, err)
}
return nil
}