
- Add comprehensive Git workflow automation tools - Include branch management utilities - Add commit helpers with conventional commit support - Implement GitHub integration for PR management - Add configuration management system - Include comprehensive test coverage - Add professional documentation and examples
126 lines
2.7 KiB
Go
126 lines
2.7 KiB
Go
package git
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"os/exec"
|
|
"strings"
|
|
)
|
|
|
|
func run(ctx context.Context, args ...string) (string, error) {
|
|
cmd := exec.CommandContext(ctx, "git", args...)
|
|
var out bytes.Buffer
|
|
var errb bytes.Buffer
|
|
cmd.Stdout = &out
|
|
cmd.Stderr = &errb
|
|
if err := cmd.Run(); err != nil {
|
|
if errb.Len() > 0 {
|
|
return "", fmtError(errb.String())
|
|
}
|
|
return "", err
|
|
}
|
|
return strings.TrimSpace(out.String()), nil
|
|
}
|
|
|
|
// Run is a public version of run for use in other packages
|
|
func Run(ctx context.Context, args ...string) (string, error) {
|
|
return run(ctx, args...)
|
|
}
|
|
|
|
func Fetch(ctx context.Context) error {
|
|
_, err := run(ctx, "fetch", "--prune")
|
|
return err
|
|
}
|
|
|
|
func RebaseOntoTracking(ctx context.Context) error {
|
|
branch, err := CurrentBranch(ctx)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
up, err := UpstreamFor(ctx, branch)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = run(ctx, "rebase", up)
|
|
return err
|
|
}
|
|
|
|
func PushCurrent(ctx context.Context, forceWithLease bool) error {
|
|
args := []string{"push"}
|
|
if forceWithLease {
|
|
args = append(args, "--force-with-lease")
|
|
}
|
|
args = append(args, "--set-upstream", "origin", "HEAD")
|
|
_, err := run(ctx, args...)
|
|
return err
|
|
}
|
|
|
|
func LocalBranches(ctx context.Context) ([]string, error) {
|
|
out, err := run(ctx, "branch", "--format=%(refname:short)")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if out == "" {
|
|
return nil, nil
|
|
}
|
|
return strings.Split(out, "\n"), nil
|
|
}
|
|
|
|
func DeleteBranch(ctx context.Context, name string) error {
|
|
_, err := run(ctx, "branch", "-D", name)
|
|
return err
|
|
}
|
|
|
|
func CurrentBranch(ctx context.Context) (string, error) {
|
|
return run(ctx, "rev-parse", "--abbrev-ref", "HEAD")
|
|
}
|
|
|
|
func UpstreamFor(ctx context.Context, branch string) (string, error) {
|
|
return run(ctx, "rev-parse", "--abbrev-ref", branch+"@{upstream}")
|
|
}
|
|
|
|
func CreateBranch(ctx context.Context, name string) error {
|
|
_, err := run(ctx, "checkout", "-b", name)
|
|
return err
|
|
}
|
|
|
|
func SwitchBranch(ctx context.Context, name string) error {
|
|
_, err := run(ctx, "checkout", name)
|
|
return err
|
|
}
|
|
|
|
func IsCleanWorkingDir(ctx context.Context) (bool, error) {
|
|
out, err := run(ctx, "status", "--porcelain")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
return out == "", nil
|
|
}
|
|
|
|
func AddAll(ctx context.Context) error {
|
|
_, err := run(ctx, "add", "-A")
|
|
return err
|
|
}
|
|
|
|
func Commit(ctx context.Context, message string) error {
|
|
_, err := run(ctx, "commit", "-m", message)
|
|
return err
|
|
}
|
|
|
|
func fmtError(s string) error {
|
|
return &gitError{msg: strings.TrimSpace(s)}
|
|
}
|
|
|
|
type gitError struct {
|
|
msg string
|
|
}
|
|
|
|
func (e *gitError) Error() string {
|
|
return e.msg
|
|
}
|
|
|
|
// GetRemoteURL returns the URL of the specified remote
|
|
func GetRemoteURL(ctx context.Context, remote string) (string, error) {
|
|
return run(ctx, "remote", "get-url", remote)
|
|
}
|