@@ -8,8 +8,20 @@ import (
88 "strings"
99)
1010
11+ // httpsHost extracts the host from an HTTPS URL, or empty string if not HTTPS.
12+ func httpsHost (url string ) string {
13+ if ! strings .HasPrefix (url , "https://" ) {
14+ return ""
15+ }
16+ withoutScheme := strings .TrimPrefix (url , "https://" )
17+ if idx := strings .Index (withoutScheme , "/" ); idx != - 1 {
18+ return withoutScheme [:idx ]
19+ }
20+ return withoutScheme
21+ }
22+
1123// UpdateRepository updates a git repository to the latest version.
12- // When useSSH is true, HTTPS GitHub remote URLs are forced to SSH for this
24+ // When useSSH is true, HTTPS remote URLs are forced to SSH for this
1325// update via a transient url.insteadOf config override, without modifying the
1426// repository's configured remote URLs.
1527func UpdateRepository (repoPath string , useSSH bool ) error {
@@ -22,15 +34,38 @@ func UpdateRepository(repoPath string, useSSH bool) error {
2234 }
2335 currentBranch := strings .TrimSpace (string (branch ))
2436
25- // gitArgs builds a git command scoped to the repo, prepending an SSH
26- // url.insteadOf override when useSSH is set so HTTPS GitHub URLs are
27- // transparently rewritten to SSH for the duration of this command only.
37+ // Build url.insteadOf overrides for all HTTPS remotes when useSSH is set.
38+ var sshOverrides []string
39+ if useSSH {
40+ remotesCmd := exec .Command ("git" , "remote" )
41+ remotesCmd .Dir = repoPath
42+ remotesOut , err := remotesCmd .Output ()
43+ if err == nil {
44+ for _ , remote := range strings .Split (strings .TrimSpace (string (remotesOut )), "\n " ) {
45+ if remote == "" {
46+ continue
47+ }
48+ urlCmd := exec .Command ("git" , "remote" , "get-url" , remote )
49+ urlCmd .Dir = repoPath
50+ urlOut , err := urlCmd .Output ()
51+ if err != nil {
52+ continue
53+ }
54+ remoteURL := strings .TrimSpace (string (urlOut ))
55+ if host := httpsHost (remoteURL ); host != "" {
56+ sshOverrides = append (sshOverrides ,
57+ "-c" , fmt .Sprintf ("url.git@%s:.insteadOf=https://%s/" , host , host ))
58+ }
59+ }
60+ }
61+ }
62+
63+ // gitArgs builds a git command scoped to the repo, prepending SSH
64+ // url.insteadOf overrides when useSSH is set.
2865 gitArgs := func (subcmd ... string ) * exec.Cmd {
2966 args := subcmd
30- if useSSH {
31- args = append ([]string {
32- "-c" , "url.git@github.com:.insteadOf=https://github.com/" ,
33- }, args ... )
67+ if len (sshOverrides ) > 0 {
68+ args = append (sshOverrides , args ... )
3469 }
3570 c := exec .Command ("git" , args ... )
3671 c .Dir = repoPath
0 commit comments