diff --git a/git/gogit/clone.go b/git/gogit/clone.go index f856b1b8b..bd6ae9a9f 100644 --- a/git/gogit/clone.go +++ b/git/gogit/clone.go @@ -165,9 +165,10 @@ func (g *Client) cloneTag(ctx context.Context, url, tag string, opts repository. Depth: depth, RecurseSubmodules: recurseSubmodules(opts.RecurseSubmodules), Progress: nil, - Tags: extgogit.NoTags, - CABundle: caBundle(g.authOpts), - ProxyOptions: g.proxy, + // Ask for the tag object that points to the commit to be sent as well. + Tags: extgogit.TagFollowing, + CABundle: caBundle(g.authOpts), + ProxyOptions: g.proxy, } repo, err := extgogit.CloneContext(ctx, g.storer, g.worktreeFS, cloneOpts) @@ -189,8 +190,27 @@ func (g *Client) cloneTag(ctx context.Context, url, tag string, opts repository. if err != nil { return nil, fmt.Errorf("unable to resolve commit object for HEAD '%s': %w", head.Hash(), err) } + commit, err := buildCommitWithRef(cc, ref) + if err != nil { + return nil, err + } + + tagRef, err := repo.Tag(tag) + if err != nil { + return nil, fmt.Errorf("unable to find reference for tag '%s': %w", tag, err) + } + tagObj, err := repo.TagObject(tagRef.Hash()) + if err != nil { + return nil, fmt.Errorf("unable to resolve tag object for tag '%s' with hash '%s': %w", tag, tagRef.Hash(), err) + } + annotatedTag, err := buildTag(tagObj) + if err != nil { + return nil, err + } + + commit.Parent = annotatedTag g.repository = repo - return buildCommitWithRef(cc, ref) + return commit, nil } func (g *Client) cloneCommit(ctx context.Context, url, commit string, opts repository.CloneConfig) (*git.Commit, error) { @@ -488,6 +508,34 @@ func buildSignature(s object.Signature) git.Signature { } } +func buildTag(t *object.Tag) (*git.AnnotatedTag, error) { + if t == nil { + return nil, fmt.Errorf("unable to contruct tag: no object") + } + + encoded := &plumbing.MemoryObject{} + if err := t.EncodeWithoutSignature(encoded); err != nil { + return nil, fmt.Errorf("unable to encode commit '%s': %w", t.Hash, err) + } + reader, err := encoded.Reader() + if err != nil { + return nil, fmt.Errorf("unable to encode commit '%s': %w", t.Hash, err) + } + b, err := io.ReadAll(reader) + if err != nil { + return nil, fmt.Errorf("unable to read encoded commit '%s': %w", t.Hash, err) + } + + return &git.AnnotatedTag{ + Hash: []byte(t.Hash.String()), + Name: t.Name, + Author: buildSignature(t.Tagger), + Signature: t.PGPSignature, + Encoded: b, + Message: t.Message, + }, nil +} + func buildCommitWithRef(c *object.Commit, ref plumbing.ReferenceName) (*git.Commit, error) { if c == nil { return nil, fmt.Errorf("unable to construct commit: no object")