11package controllers
22
33import (
4+ "errors"
45 "fmt"
56 "regexp"
67 "slices"
@@ -143,8 +144,8 @@ func (self *RemotesController) enter(remote *models.Remote) error {
143144 return nil
144145}
145146
146- // Adds a new remote and refreshes the list of remotes .
147- func (self * RemotesController ) addRemoteAndRefresh (remoteName string , remoteUrl string ) error {
147+ // Adds a new remote, refreshes and selects it, then fetches and checks out the specified branch if provided .
148+ func (self * RemotesController ) addAndCheckoutRemote (remoteName string , remoteUrl string , branchToCheckout string ) error {
148149 self .c .LogAction (self .c .Tr .Actions .AddRemote )
149150 err := self .c .Git ().Remote .AddRemote (remoteName , remoteUrl )
150151 if err != nil {
@@ -158,11 +159,7 @@ func (self *RemotesController) addRemoteAndRefresh(remoteName string, remoteUrl
158159 Scope : []types.RefreshableView {types .REMOTES },
159160 Mode : types .SYNC ,
160161 })
161- return nil
162- }
163162
164- // Selects the given remote in the UI, fetches it, and checks out the specified branch if profided.
165- func (self * RemotesController ) selectRemoteAndCheckout (remoteName string , remoteUrl string , branchToCheckout string ) error {
166163 // Select the remote
167164 for idx , remote := range self .c .Model ().Remotes {
168165 if remote .Name == remoteName {
@@ -175,13 +172,6 @@ func (self *RemotesController) selectRemoteAndCheckout(remoteName string, remote
175172 return self .fetchAndCheckout (self .c .Contexts ().Remotes .GetSelected (), branchToCheckout )
176173}
177174
178- // Adds a new remote, refreshes and selects it, then fetches and checks out the specified branch if provided.
179- func (self * RemotesController ) addAndCheckoutRemote (remoteName string , remoteUrl string , branchToCheckout string ) error {
180- self .addRemoteAndRefresh (remoteName , remoteUrl )
181-
182- return self .selectRemoteAndCheckout (remoteName , remoteUrl , branchToCheckout )
183- }
184-
185175// Ensures the fork remote exists (matching the given URL).
186176// If it exists and matches, it’s selected and fetched; otherwise, it’s created and then fetched and checked out.
187177// If it does exist but with a different URL, an error is returned.
@@ -190,7 +180,7 @@ func (self *RemotesController) ensureForkRemoteAndCheckout(remoteName string, re
190180 if remote .Name == remoteName {
191181 hasTheSameUrl := slices .Contains (remote .Urls , remoteUrl )
192182 if ! hasTheSameUrl {
193- return fmt . Errorf ( "%s" , utils .ResolvePlaceholderString (
183+ return errors . New ( utils .ResolvePlaceholderString (
194184 self .c .Tr .IncompatibleForkAlreadyExistsError ,
195185 map [string ]string {
196186 "remoteName" : remoteName ,
@@ -222,37 +212,27 @@ func (self *RemotesController) add() error {
222212 return nil
223213}
224214
225- var (
226- // 1. SCP-like SSH: git@host:owner[/subgroups]/repo(.git)
227- sshScpRegex = regexp .MustCompile (`^(git@[^:]+:)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$` )
228-
229- // 2. SSH URL style: ssh://user@host[:port]/owner[/subgroups]/repo(.git)
230- sshUrlRegex = regexp .MustCompile (`^(ssh://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$` )
231-
232- // 3. HTTPS: https://host/owner[/subgroups]/repo(.git)
233- httpRegex = regexp .MustCompile (`^(https?://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$` )
234- )
215+ // Regex to match and capture parts of a Git remote URL. Supports the following formats:
216+ // 1. SCP-like SSH: git@host:owner[/subgroups]/repo(.git)
217+ // 2. SSH URL style: ssh://user@host[:port]/owner[/subgroups]/repo(.git)
218+ // 3. HTTPS: https://host/owner[/subgroups]/repo(.git)
219+ var urlRegex = regexp .MustCompile (`^(git@[^:]+:|ssh://[^/]+/|https?://[^/]+/)([^/]+(?:/[^/]+)*)/([^/]+?)(\.git)?$` )
235220
236221// Rewrites a Git remote URL to use the given fork username,
237222// keeping the repo name and host intact. Supports SCP-like SSH, SSH URL style, and HTTPS.
238223func replaceForkUsername (remoteUrl , forkUsername string ) (string , error ) {
239224 if forkUsername == "" {
240- return "" , fmt . Errorf ("fork username cannot be empty" )
225+ return "" , errors . New ("fork username cannot be empty" )
241226 }
242227 if remoteUrl == "" {
243- return "" , fmt . Errorf ("remote URL cannot be empty" )
228+ return "" , errors . New ("remote URL cannot be empty" )
244229 }
245230
246- switch {
247- case sshScpRegex .MatchString (remoteUrl ):
248- return sshScpRegex .ReplaceAllString (remoteUrl , "${1}" + forkUsername + "/$3$4" ), nil
249- case sshUrlRegex .MatchString (remoteUrl ):
250- return sshUrlRegex .ReplaceAllString (remoteUrl , "${1}" + forkUsername + "/$3$4" ), nil
251- case httpRegex .MatchString (remoteUrl ):
252- return httpRegex .ReplaceAllString (remoteUrl , "${1}" + forkUsername + "/$3$4" ), nil
253- default :
254- return "" , fmt .Errorf ("unsupported or invalid remote URL: %s" , remoteUrl )
231+ if urlRegex .MatchString (remoteUrl ) {
232+ return urlRegex .ReplaceAllString (remoteUrl , "${1}" + forkUsername + "/$3$4" ), nil
255233 }
234+
235+ return "" , fmt .Errorf ("unsupported or invalid remote URL: %s" , remoteUrl )
256236}
257237
258238func (self * RemotesController ) addFork (baseRemote * models.Remote ) error {
0 commit comments