MCPcopy Create free account
hub / github.com/coder/envbuilder / CloneRepo

Function CloneRepo

git/git.go:51–136  ·  view source on GitHub ↗

CloneRepo will clone the repository at the given URL into the given path. If a repository is already initialized at the given path, it will not be cloned again. The bool returned states whether the repository was cloned or not.

(ctx context.Context, logf func(string, ...any), opts CloneRepoOptions)

Source from the content-addressed store, hash-verified

49//
50// The bool returned states whether the repository was cloned or not.
51func CloneRepo(ctx context.Context, logf func(string, ...any), opts CloneRepoOptions) (bool, error) {
52 parsed, err := ebutil.ParseRepoURL(opts.RepoURL)
53 if err != nil {
54 return false, fmt.Errorf("parse url %q: %w", opts.RepoURL, err)
55 }
56
57 thinPack := true
58
59 if !opts.ThinPack {
60 thinPack = false
61 logf("ThinPack options is false, Marking thin-pack as unsupported")
62 } else if parsed.Host == "dev.azure.com" {
63 // Azure DevOps requires capabilities multi_ack / multi_ack_detailed,
64 // which are not fully implemented and by default are included in
65 // transport.UnsupportedCapabilities.
66 //
67 // The initial clone operations require a full download of the repository,
68 // and therefore those unsupported capabilities are not as crucial, so
69 // by removing them from that list allows for the first clone to work
70 // successfully.
71 //
72 // Additional fetches will yield issues, therefore work always from a clean
73 // clone until those capabilities are fully supported.
74 //
75 // New commits and pushes against a remote worked without any issues.
76 // See: https://github.com/go-git/go-git/issues/64
77 //
78 // This is knowingly not safe to call in parallel, but it seemed
79 // like the least-janky place to add a super janky hack.
80 thinPack = false
81 logf("Workaround for Azure DevOps: marking thin-pack as unsupported")
82 }
83
84 if !thinPack {
85 transport.UnsupportedCapabilities = []capability.Capability{
86 capability.ThinPack,
87 }
88 }
89
90 err = opts.Storage.MkdirAll(opts.Path, 0o755)
91 if err != nil {
92 return false, fmt.Errorf("mkdir %q: %w", opts.Path, err)
93 }
94 if parsed.Reference == "" && opts.SingleBranch {
95 parsed.Reference = "refs/heads/main"
96 }
97 fs, err := opts.Storage.Chroot(opts.Path)
98 if err != nil {
99 return false, fmt.Errorf("chroot %q: %w", opts.Path, err)
100 }
101 gitDir, err := fs.Chroot(".git")
102 if err != nil {
103 return false, fmt.Errorf("chroot .git: %w", err)
104 }
105 gitStorage := filesystem.NewStorage(gitDir, cache.NewObjectLRU(cache.DefaultMaxSize*10))
106 fsStorage := filesystem.NewStorage(fs, cache.NewObjectLRU(cache.DefaultMaxSize*10))
107 repo, err := git.Open(fsStorage, gitDir)
108 if errors.Is(err, git.ErrRepositoryNotExists) {

Callers 5

runFunction · 0.92
RunCacheProbeFunction · 0.92
TestCloneRepoFunction · 0.92
TestCloneRepoSSHFunction · 0.92
ShallowCloneRepoFunction · 0.85

Calls 2

ParseRepoURLFunction · 0.92
MkdirAllMethod · 0.65

Tested by 2

TestCloneRepoFunction · 0.74
TestCloneRepoSSHFunction · 0.74