extractHostFromRemoteURL extracts the host (optionally including port) from a git remote URL. Supports HTTPS (https://host[:port]/path), HTTP (http://host[:port]/path), and SSH (git@host[:port]:path or ssh://git@host[:port]/path) formats. Returns the host portion as "host[:port]" when parsed, or "gi
(remoteURL string)
| 100 | // Supports HTTPS (https://host[:port]/path), HTTP (http://host[:port]/path), and SSH (git@host[:port]:path or ssh://git@host[:port]/path) formats. |
| 101 | // Returns the host portion as "host[:port]" when parsed, or "github.com" as the default if the URL cannot be parsed. |
| 102 | func extractHostFromRemoteURL(remoteURL string) string { |
| 103 | // HTTPS / HTTP format: https://[userinfo@]host/path or http://[userinfo@]host/path |
| 104 | // Use net/url.Parse to correctly handle all userinfo variants (user@, user:pass@, |
| 105 | // and passwords containing '@') and to extract the bare host without credentials. |
| 106 | for _, scheme := range []string{"https://", "http://"} { |
| 107 | if strings.HasPrefix(remoteURL, scheme) { |
| 108 | if u, err := url.Parse(remoteURL); err == nil && u.Host != "" { |
| 109 | return u.Host |
| 110 | } |
| 111 | // Fallback: strip scheme and any userinfo manually. |
| 112 | after := remoteURL[len(scheme):] |
| 113 | if host, _, found := strings.Cut(after, "/"); found { |
| 114 | // Strip optional userinfo (everything up to and including the last '@'). |
| 115 | if idx := strings.LastIndex(host, "@"); idx >= 0 { |
| 116 | host = host[idx+1:] |
| 117 | } |
| 118 | return host |
| 119 | } |
| 120 | if idx := strings.LastIndex(after, "@"); idx >= 0 { |
| 121 | return after[idx+1:] |
| 122 | } |
| 123 | return after |
| 124 | } |
| 125 | } |
| 126 | |
| 127 | // SSH scp-like format: git@host:path |
| 128 | if after, ok := strings.CutPrefix(remoteURL, "git@"); ok { |
| 129 | if host, _, found := strings.Cut(after, ":"); found { |
| 130 | return host |
| 131 | } |
| 132 | } |
| 133 | |
| 134 | // SSH URL format: ssh://git@host/path or ssh://host/path |
| 135 | if after, ok := strings.CutPrefix(remoteURL, "ssh://"); ok { |
| 136 | // Strip optional user info (e.g. "git@") |
| 137 | if _, userStripped, hasAt := strings.Cut(after, "@"); hasAt { |
| 138 | after = userStripped |
| 139 | } |
| 140 | if host, _, found := strings.Cut(after, "/"); found { |
| 141 | return host |
| 142 | } |
| 143 | return after |
| 144 | } |
| 145 | |
| 146 | return "github.com" |
| 147 | } |
| 148 | |
| 149 | // resolveRemoteURL resolves the best git remote URL to use for a given directory. |
| 150 | // It first tries the 'origin' remote for backward compatibility. If 'origin' is not |
no outgoing calls