Skip to content

Commit 4f29459

Browse files
committed
libgit2: Update checkout to respect context
Update libgit2-git2go checkout with a clone wrapper to respect the context passed to it. go-git accepts context passed to it during cloning but the git2go does not accept the context passed to it. This makes the GitRepository.Spec.Timeout ineffective when using libgit2. This change updates all the different libgit2 checkouts to use the new clone function. This is also needed to shorten the wait time for tests that depend on failure behavior and should fail early. TestCheckout_ED25519 test would take 30s without a context with timeout. This helps shorten the time for such tests. Signed-off-by: Sunny <[email protected]>
1 parent 8fa174e commit 4f29459

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

pkg/git/libgit2/checkout.go

+38-12
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,34 @@ func CheckoutStrategyForRef(ref *sourcev1.GitRepositoryRef, opt git.CheckoutOpti
5353
}
5454
}
5555

56+
// clone is a wrapper around git2go.Clone that respects the provided context.
57+
func clone(ctx context.Context, path, url string, auth *git.Auth, opts *git2go.CloneOptions) (*git2go.Repository, error) {
58+
var repo *git2go.Repository
59+
errCh := make(chan error, 1)
60+
go func() {
61+
var err error
62+
repo, err = git2go.Clone(url, path, opts)
63+
errCh <- err
64+
}()
65+
66+
select {
67+
case err := <-errCh:
68+
if err != nil {
69+
return nil, fmt.Errorf("unable to clone '%s': %w", url, gitutil.LibGit2Error(err))
70+
}
71+
case <-ctx.Done():
72+
return nil, fmt.Errorf("clone context cancelled: %w", ctx.Err())
73+
}
74+
75+
return repo, nil
76+
}
77+
5678
type CheckoutBranch struct {
5779
branch string
5880
}
5981

6082
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
61-
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
83+
cloneOpts := &git2go.CloneOptions{
6284
FetchOptions: &git2go.FetchOptions{
6385
DownloadTags: git2go.DownloadTagsNone,
6486
RemoteCallbacks: git2go.RemoteCallbacks{
@@ -67,9 +89,10 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, auth *g
6789
},
6890
},
6991
CheckoutBranch: c.branch,
70-
})
92+
}
93+
repo, err := clone(ctx, path, url, auth, cloneOpts)
7194
if err != nil {
72-
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, gitutil.LibGit2Error(err))
95+
return nil, "", err
7396
}
7497
head, err := repo.Head()
7598
if err != nil {
@@ -87,17 +110,18 @@ type CheckoutTag struct {
87110
}
88111

89112
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
90-
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
113+
cloneOpts := &git2go.CloneOptions{
91114
FetchOptions: &git2go.FetchOptions{
92115
DownloadTags: git2go.DownloadTagsAll,
93116
RemoteCallbacks: git2go.RemoteCallbacks{
94117
CredentialsCallback: auth.CredCallback,
95118
CertificateCheckCallback: auth.CertCallback,
96119
},
97120
},
98-
})
121+
}
122+
repo, err := clone(ctx, path, url, auth, cloneOpts)
99123
if err != nil {
100-
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
124+
return nil, "", err
101125
}
102126
ref, err := repo.References.Dwim(c.tag)
103127
if err != nil {
@@ -131,7 +155,7 @@ type CheckoutCommit struct {
131155
}
132156

133157
func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *git.Auth) (git.Commit, string, error) {
134-
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
158+
cloneOpts := &git2go.CloneOptions{
135159
FetchOptions: &git2go.FetchOptions{
136160
DownloadTags: git2go.DownloadTagsNone,
137161
RemoteCallbacks: git2go.RemoteCallbacks{
@@ -140,9 +164,10 @@ func (c *CheckoutCommit) Checkout(ctx context.Context, path, url string, auth *g
140164
},
141165
},
142166
CheckoutBranch: c.branch,
143-
})
167+
}
168+
repo, err := clone(ctx, path, url, auth, cloneOpts)
144169
if err != nil {
145-
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
170+
return nil, "", err
146171
}
147172
oid, err := git2go.NewOid(c.commit)
148173
if err != nil {
@@ -176,17 +201,18 @@ func (c *CheckoutSemVer) Checkout(ctx context.Context, path, url string, auth *g
176201
return nil, "", fmt.Errorf("semver parse range error: %w", err)
177202
}
178203

179-
repo, err := git2go.Clone(url, path, &git2go.CloneOptions{
204+
cloneOpts := &git2go.CloneOptions{
180205
FetchOptions: &git2go.FetchOptions{
181206
DownloadTags: git2go.DownloadTagsAll,
182207
RemoteCallbacks: git2go.RemoteCallbacks{
183208
CredentialsCallback: auth.CredCallback,
184209
CertificateCheckCallback: auth.CertCallback,
185210
},
186211
},
187-
})
212+
}
213+
repo, err := clone(ctx, path, url, auth, cloneOpts)
188214
if err != nil {
189-
return nil, "", fmt.Errorf("unable to clone '%s', error: %w", url, err)
215+
return nil, "", err
190216
}
191217

192218
tags := make(map[string]string)

0 commit comments

Comments
 (0)