@@ -27,6 +27,7 @@ type GitGetter struct {
27
27
}
28
28
29
29
var defaultBranchRegexp = regexp .MustCompile (`\s->\sorigin/(.*)` )
30
+ var lsRemoteSymRefRegexp = regexp .MustCompile (`ref: refs/heads/([^\s]+).*` )
30
31
31
32
func (g * GitGetter ) ClientMode (_ * url.URL ) (ClientMode , error ) {
32
33
return ClientModeDir , nil
@@ -114,7 +115,7 @@ func (g *GitGetter) Get(dst string, u *url.URL) error {
114
115
if err == nil {
115
116
err = g .update (ctx , dst , sshKeyFile , ref , depth )
116
117
} else {
117
- err = g .clone (ctx , dst , sshKeyFile , u , depth )
118
+ err = g .clone (ctx , dst , sshKeyFile , u , ref , depth )
118
119
}
119
120
if err != nil {
120
121
return err
@@ -166,14 +167,17 @@ func (g *GitGetter) checkout(dst string, ref string) error {
166
167
return getRunCommand (cmd )
167
168
}
168
169
169
- func (g * GitGetter ) clone (ctx context.Context , dst , sshKeyFile string , u * url.URL , depth int ) error {
170
+ func (g * GitGetter ) clone (ctx context.Context , dst , sshKeyFile string , u * url.URL , ref string , depth int ) error {
170
171
args := []string {"clone" }
171
172
173
+ if ref == "" {
174
+ ref = findRemoteDefaultBranch (u )
175
+ }
172
176
if depth > 0 {
173
177
args = append (args , "--depth" , strconv .Itoa (depth ))
174
178
}
175
179
176
- args = append (args , u .String (), dst )
180
+ args = append (args , "--branch" , ref , u .String (), dst )
177
181
cmd := exec .CommandContext (ctx , "git" , args ... )
178
182
setupGitEnv (cmd , sshKeyFile )
179
183
return getRunCommand (cmd )
@@ -236,6 +240,20 @@ func findDefaultBranch(dst string) string {
236
240
return matches [len (matches )- 1 ]
237
241
}
238
242
243
+ // findRemoteDefaultBranch checks the remote repo's HEAD symref to return the remote repo's
244
+ // default branch. "master" is returned if no HEAD symref exists.
245
+ func findRemoteDefaultBranch (u * url.URL ) string {
246
+ var stdoutbuf bytes.Buffer
247
+ cmd := exec .Command ("git" , "ls-remote" , "--symref" , u .String (), "HEAD" )
248
+ cmd .Stdout = & stdoutbuf
249
+ err := cmd .Run ()
250
+ matches := lsRemoteSymRefRegexp .FindStringSubmatch (stdoutbuf .String ())
251
+ if err != nil || matches == nil {
252
+ return "master"
253
+ }
254
+ return matches [len (matches )- 1 ]
255
+ }
256
+
239
257
// setupGitEnv sets up the environment for the given command. This is used to
240
258
// pass configuration data to git and ssh and enables advanced cloning methods.
241
259
func setupGitEnv (cmd * exec.Cmd , sshKeyFile string ) {
0 commit comments