@@ -138,37 +138,47 @@ func (g *GitClient) Clone(ctx context.Context, clonePath string, url string, tok
138138
139139 switch {
140140 case ref == "HEAD" :
141- // Try "main" first (most common), then "master", then ls-remote as fallback
142- for _ , branch := range []string {"main" , "master" } {
141+ // Discover the actual default branch via ls-remote HEAD symref.
142+ // Doing this first (rather than fast-pathing to main/master) avoids
143+ // analyzing the wrong branch on repositories whose default is not main.
144+ discovered := discoverDefaultBranch (repo , token )
145+ if discovered != "" {
143146 fetchOpts .RefSpecs = []config.RefSpec {
144- config .RefSpec (fmt .Sprintf ("+refs/heads/%s:refs/remotes/origin/%s" , branch , branch )),
147+ config .RefSpec (fmt .Sprintf ("+refs/heads/%s:refs/remotes/origin/%s" , discovered , discovered )),
145148 }
146149 err = repo .FetchContext (ctx , fetchOpts )
147150 if err == nil {
148- defaultBranch = branch
149- resolved .localRef = plumbing .ReferenceName ("refs/remotes/origin/" + branch )
150- break
151- }
152- if classifyFetchError (err ) != nil && ! strings .Contains (err .Error (), "couldn't find remote ref" ) {
153- return classifyFetchError (err )
151+ defaultBranch = discovered
152+ resolved .localRef = plumbing .ReferenceName ("refs/remotes/origin/" + discovered )
153+ } else if cerr := classifyFetchError (err ); cerr != nil && ! strings .Contains (err .Error (), "couldn't find remote ref" ) {
154+ return cerr
154155 }
155156 }
156157 if defaultBranch == "" {
157- // Neither main nor master — ls-remote to find actual default
158- discovered := discoverDefaultBranchFromURL (url , token )
159- if discovered != "" {
158+ // Discovery failed (e.g. server didn't advertise HEAD, or fetch of
159+ // discovered branch failed). Try common defaults before falling
160+ // back to fetching all branches.
161+ for _ , branch := range []string {"main" , "master" } {
160162 fetchOpts .RefSpecs = []config.RefSpec {
161- config .RefSpec (fmt .Sprintf ("+refs/heads/%s:refs/remotes/origin/%s" , discovered , discovered )),
163+ config .RefSpec (fmt .Sprintf ("+refs/heads/%s:refs/remotes/origin/%s" , branch , branch )),
164+ }
165+ err = repo .FetchContext (ctx , fetchOpts )
166+ if err == nil {
167+ defaultBranch = branch
168+ resolved .localRef = plumbing .ReferenceName ("refs/remotes/origin/" + branch )
169+ break
170+ }
171+ if cerr := classifyFetchError (err ); cerr != nil && ! strings .Contains (err .Error (), "couldn't find remote ref" ) {
172+ return cerr
162173 }
163- resolved .localRef = plumbing .ReferenceName ("refs/remotes/origin/" + discovered )
164- } else {
165- fetchOpts .RefSpecs = []config.RefSpec {config .RefSpec ("+refs/heads/*:refs/remotes/origin/*" )}
166174 }
175+ }
176+ if defaultBranch == "" {
177+ fetchOpts .RefSpecs = []config.RefSpec {config .RefSpec ("+refs/heads/*:refs/remotes/origin/*" )}
167178 err = repo .FetchContext (ctx , fetchOpts )
168179 if err := classifyFetchError (err ); err != nil {
169180 return err
170181 }
171- defaultBranch = discovered
172182 }
173183 default :
174184 resolved , err = resolveRemoteRef (repo , url , token , ref )
@@ -772,20 +782,10 @@ func peelToCommit(store storer.EncodedObjectStorer, hash plumbing.Hash) (plumbin
772782 }
773783}
774784
775- // looksLikeSHA returns true if s looks like a full-length git commit SHA.
776- // discoverDefaultBranch uses remote.List to find the HEAD symref target.
777- // Returns empty string if it can't be determined.
778- // discoverDefaultBranchFromURL does a lightweight ls-remote to find the HEAD symref.
779- func discoverDefaultBranchFromURL (url string , token string ) string {
780- store := memory .NewStorage ()
781- repo , err := gogit .Init (store , nil )
782- if err != nil {
783- return ""
784- }
785- _ , err = repo .CreateRemote (& config.RemoteConfig {Name : "origin" , URLs : []string {url }})
786- if err != nil {
787- return ""
788- }
785+ // discoverDefaultBranch performs a lightweight ls-remote on the repo's origin
786+ // remote and returns the branch name that HEAD points to. Returns "" when the
787+ // server doesn't advertise a HEAD symref or the listing fails.
788+ func discoverDefaultBranch (repo * gogit.Repository , token string ) string {
789789 remote , err := repo .Remote ("origin" )
790790 if err != nil {
791791 return ""
0 commit comments