Something went wrong. Try again.
forked from rockorager.dev/knit
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160package git
import ( "bufio" "fmt" "net/url" "os" "os/exec" "path" "sort" "strings")
type Remote = struct { Name string Host string Path string}
// Remotes gets the configured git remotes for the current working directoryfunc Remotes() ([]*Remote, error) { cmd := exec.Command("git", "remote", "--verbose")
output, err := cmd.Output() if err != nil { return nil, err }
remotes := []*Remote{}
scanner := bufio.NewScanner(strings.NewReader(string(output)))outer: for scanner.Scan() { line := scanner.Text() fields := strings.Fields(line) if len(fields) != 3 { continue } if fields[2] != "(fetch)" { continue }
u, err := normalizeGitURL(fields[1]) if err != nil { continue } u.Name = fields[0]
for _, remote := range remotes { if remote.Host == u.Host && remote.Path == u.Path { continue outer } }
remotes = append(remotes, u) }
return remotes, nil}
func normalizeGitURL(raw string) (*Remote, error) { // Handle SSH-style: git@github.com:user/repo.git if at := strings.Index(raw, "@"); at != -1 { colon := strings.Index(raw, ":") if colon == -1 || colon < at { return nil, fmt.Errorf("invalid SSH Git URL: %s", raw) }
host := raw[at+1 : colon] path := raw[colon+1:] return &Remote{ Host: host, Path: path, }, nil }
// Handle HTTPS-style if strings.HasPrefix(raw, "http://") || strings.HasPrefix(raw, "https://") { u, err := url.Parse(raw) if err != nil { return nil, fmt.Errorf("invalid URL: %w", err) }
return &Remote{ Host: u.Host, Path: strings.TrimPrefix(u.Path, "/"), }, nil }
return nil, fmt.Errorf("unsupported Git URL format: %s", raw)}
func FormatPatch(revRange string) (string, error) { cmd := exec.Command("git", "format-patch", "--stdout", revRange)
output, err := cmd.Output() if err != nil { return "", err }
return string(output), nil}
func FormatPatchToTmp(revRange string) ([]string, error) { tmpDir, err := os.MkdirTemp("", "knit-patches-") if err != nil { return nil, err }
cmd := exec.Command( "git", "format-patch", "--output-directory", tmpDir, revRange, ) if err := cmd.Run(); err != nil { return nil, err }
entries, err := os.ReadDir(tmpDir) if err != nil { return nil, err }
var paths []string for _, entry := range entries { if entry.IsDir() { continue } paths = append(paths, path.Join(tmpDir, entry.Name())) } sort.Strings(paths) return paths, nil}
func RemoteBranches(remote string) ([]string, error) { cmd := exec.Command("git", "branch", "--remotes", "--list", remote+"*")
output, err := cmd.Output() if err != nil { return nil, err }
branches := []string{} scanner := bufio.NewScanner(strings.NewReader(string(output)))
for scanner.Scan() { line := strings.TrimSpace(scanner.Text()) branch := strings.TrimPrefix(line, remote+"/") if strings.HasPrefix(branch, "HEAD ->") { continue }
branches = append(branches, branch)
} return branches, nil}