func cloneGitRepo()

in scan/git.go [63:120]


func cloneGitRepo(repo gitRepo, root string) (checkoutDir string, err error) {
	fetch := fetchArgs(repo.remote, repo.ref)
	if err != nil {
		return "", err
	}

	defer func() {
		if err != nil {
			_ = os.RemoveAll(root)
		}
	}()

	// Enable credential cache
	err = enableCredentialCache(root)
	if err != nil {
		return "", err
	}

	var out []byte
	if out, err = gitWithinDir(root, "init"); err != nil {
		return "", errors.Wrapf(err, "failed to init repo at %s: %s", root, out)
	}

	// Add origin remote for compatibility with previous implementation that
	// used "git clone" and also to make sure local refs are created for branches
	if out, err = gitWithinDir(root, "remote", "add", "origin", repo.remote); err != nil {
		return "", errors.Wrapf(err, "failed add origin repo at %s: %s", repo.remote, out)
	}

	if _, err = gitWithinDir(root, fetch...); err != nil {
		// Fall back to full fetch if shallow fetch fails.
		// It's mainly for the scenario if the reference is a git commit,
		// eg, https://github.com/abc.git#bcaf8913695e5ad57868c8c82af58f9e699e7f59
		if output2, err2 := gitWithinDir(root, "fetch", "origin"); err2 != nil {
			return "", errors.Wrapf(err, "error fetching: %s", censorGitPAT(output2))
		}
	}

	checkoutDir, err = checkoutGit(root, repo.ref, repo.subdir)
	if err != nil {
		return "", err
	}

	// explicitly allow file protocol to allow local unit test
	cmd := exec.Command("git", "-c", "protocol.file.allow=always", "submodule", "update", "--init", "--recursive", "--depth=1")
	cmd.Dir = root
	output, err := cmd.CombinedOutput()
	if err != nil {
		return "", errors.Wrapf(err, "error initializing submodules: %s", output)
	}

	err = gitLfs(root)
	if err != nil {
		return "", err
	}

	return checkoutDir, nil
}