libgit2: return func to help callers free git2go objects

Signed-off-by: Paulo Gomes <paulo.gomes@weave.works>
This commit is contained in:
Paulo Gomes 2022-05-11 12:27:02 +01:00
parent 87e03431b0
commit 90ef278797
No known key found for this signature in database
GPG Key ID: 9995233870E99BEE
1 changed files with 16 additions and 20 deletions

View File

@ -67,14 +67,11 @@ type CheckoutBranch struct {
func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *git.AuthOptions) (_ *git.Commit, err error) {
defer recoverPanic(&err)
repo, remote, err := getBlankRepoAndRemote(ctx, path, url, opts)
repo, remote, free, err := getBlankRepoAndRemote(ctx, path, url, opts)
if err != nil {
return nil, err
}
defer repo.Free()
defer remote.Free()
defer remote.Disconnect()
defer free()
// When the last observed revision is set, check whether it is still
// the same at the remote branch. If so, short-circuit the clone operation here.
@ -154,15 +151,11 @@ type CheckoutTag struct {
func (c *CheckoutTag) Checkout(ctx context.Context, path, url string, opts *git.AuthOptions) (_ *git.Commit, err error) {
defer recoverPanic(&err)
repo, remote, err := getBlankRepoAndRemote(ctx, path, url, opts)
repo, remote, free, err := getBlankRepoAndRemote(ctx, path, url, opts)
if err != nil {
return nil, err
}
defer repo.Free()
defer remote.Free()
defer remote.Disconnect()
defer free()
if c.LastRevision != "" {
heads, err := remote.Ls(c.Tag)
@ -416,20 +409,17 @@ func buildSignature(s *git2go.Signature) git.Signature {
}
// getBlankRepoAndRemote returns a newly initialized repository, and a remote connected to the provided url.
// Callers must make sure to call the below defer statements:
// defer repo.Free()
// defer remote.Free()
// defer remote.Disconnect()
func getBlankRepoAndRemote(ctx context.Context, path, url string, opts *git.AuthOptions) (*git2go.Repository, *git2go.Remote, error) {
// Callers must call the returning function to free all git2go objects.
func getBlankRepoAndRemote(ctx context.Context, path, url string, opts *git.AuthOptions) (*git2go.Repository, *git2go.Remote, func(), error) {
repo, err := git2go.InitRepository(path, false)
if err != nil {
return nil, nil, fmt.Errorf("unable to init repository for '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
return nil, nil, nil, fmt.Errorf("unable to init repository for '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
}
remote, err := repo.Remotes.Create("origin", url)
if err != nil {
repo.Free()
return nil, nil, fmt.Errorf("unable to create remote for '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
return nil, nil, nil, fmt.Errorf("unable to create remote for '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
}
callBacks := RemoteCallbacks(ctx, opts)
@ -437,9 +427,15 @@ func getBlankRepoAndRemote(ctx context.Context, path, url string, opts *git.Auth
if err != nil {
remote.Free()
repo.Free()
return nil, nil, fmt.Errorf("unable to fetch-connect to remote '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
return nil, nil, nil, fmt.Errorf("unable to fetch-connect to remote '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
}
return repo, remote, nil
free := func() {
remote.Disconnect()
remote.Free()
repo.Free()
}
return repo, remote, free, nil
}
func recoverPanic(err *error) {