diff --git a/libs/git/clone.go b/libs/git/clone.go index 8b075cde..af7ffa4b 100644 --- a/libs/git/clone.go +++ b/libs/git/clone.go @@ -25,31 +25,23 @@ type cloneOptions struct { // Local path to clone repository at TargetPath string + + // If true, the repository is shallow cloned + Shallow bool } func (opts cloneOptions) args() []string { - args := []string{"clone", opts.RepositoryUrl, opts.TargetPath, "--depth=1", "--no-tags"} + args := []string{"clone", opts.RepositoryUrl, opts.TargetPath, "--no-tags"} if opts.Reference != "" { args = append(args, "--branch", opts.Reference) } + if opts.Shallow { + args = append(args, "--depth=1") + } return args } -func Clone(ctx context.Context, url, reference, targetPath string) error { - // We assume only the repository name has been if input does not contain any - // `/` characters and the url is only made up of alphanumeric characters and - // ".", "_" and "-". This repository is resolved again databricks github account. - fullUrl := url - if githubRepoRegex.MatchString(url) { - fullUrl = strings.Join([]string{githubUrl, databricksOrg, url}, "/") - } - - opts := cloneOptions{ - Reference: reference, - RepositoryUrl: fullUrl, - TargetPath: targetPath, - } - +func (opts cloneOptions) clone(ctx context.Context) error { cmd := exec.CommandContext(ctx, "git", opts.args()...) var cmdErr bytes.Buffer cmd.Stderr = &cmdErr @@ -70,3 +62,29 @@ func Clone(ctx context.Context, url, reference, targetPath string) error { } return nil } + +func Clone(ctx context.Context, url, reference, targetPath string) error { + // We assume only the repository name has been if input does not contain any + // `/` characters and the url is only made up of alphanumeric characters and + // ".", "_" and "-". This repository is resolved again databricks github account. + fullUrl := url + if githubRepoRegex.MatchString(url) { + fullUrl = strings.Join([]string{githubUrl, databricksOrg, url}, "/") + } + + opts := cloneOptions{ + Reference: reference, + RepositoryUrl: fullUrl, + TargetPath: targetPath, + Shallow: true, + } + + err := opts.clone(ctx) + // Git repos hosted via HTTP do not support shallow cloning. We try with + // a deep clone this time + if err != nil && strings.Contains(err.Error(), "dumb http transport does not support shallow capabilities") { + opts.Shallow = false + return opts.clone(ctx) + } + return err +} diff --git a/libs/git/clone_test.go b/libs/git/clone_test.go index 8101178f..bed5fa54 100644 --- a/libs/git/clone_test.go +++ b/libs/git/clone_test.go @@ -10,17 +10,27 @@ import ( func TestGitCloneArgs(t *testing.T) { // case: No branch / tag specified. In this case git clones the default branch - assert.Equal(t, []string{"clone", "abc", "/def", "--depth=1", "--no-tags"}, cloneOptions{ + assert.Equal(t, []string{"clone", "abc", "/def", "--no-tags", "--depth=1"}, cloneOptions{ Reference: "", RepositoryUrl: "abc", TargetPath: "/def", + Shallow: true, }.args()) // case: A branch is specified. - assert.Equal(t, []string{"clone", "abc", "/def", "--depth=1", "--no-tags", "--branch", "my-branch"}, cloneOptions{ + assert.Equal(t, []string{"clone", "abc", "/def", "--no-tags", "--branch", "my-branch", "--depth=1"}, cloneOptions{ Reference: "my-branch", RepositoryUrl: "abc", TargetPath: "/def", + Shallow: true, + }.args()) + + // case: deep cloning + assert.Equal(t, []string{"clone", "abc", "/def", "--no-tags"}, cloneOptions{ + Reference: "", + RepositoryUrl: "abc", + TargetPath: "/def", + Shallow: false, }.args()) }