8000 Unable to checkout by tag commit id. · Issue #959 · go-git/go-git · GitHub
[go: up one dir, main page]

Skip to content
Unable to checkout by tag commit id. #959
@alee-r7

Description

@alee-r7

So I'm trying to checkout by the tag commit id. Basically I get the tag, its hash then do a checkout. Like this.

err = w.Checkout(&git.CheckoutOptions{
		Hash: commitHash,
		Force: true,
	})

I've verified the working directory has the commit, even checked objects folder by unpacking the repo I'm working with. I'm also able to checkout using the command line.

I tracked down the issue to this here. Here is the order

  1. Checkout will call Reset which calls ResetSparsely.
  2. ResetSparsely will then call getTreeFromCommitHash.
    t, err := w.r.getTreeFromCommitHash(opts.Commit)
  3. getTreeFromCommitHash will call r.CommitObject which then calls object.GetCommit.
    https://github.com/go-git/go-git/blob/master/repository.go#L1424
  4. GetCommit will then call s.EncodedObject. https://github.com/go-git/go-git/blob/master/plumbing/object/commit.go#L70
  5. This is where it fails. It seems based off the hash, the object that is retrieved from the pack or objects folder is a TabObject. However, it will fail on the last "IF" check because it expects a commit object. Due to the two types be different it returns an error.
func (s *ObjectStorage) EncodedObject(t plumbing.ObjectType, h plumbing.Hash) (plumbing.EncodedObject, error) {
	var obj plumbing.EncodedObject
	var err error

	if s.index != nil {
		obj, err = s.getFromPackfile(h, false)
		if err == plumbing.ErrObjectNotFound {
			obj, err = s.getFromUnpacked(h)
		}
	} else {
		obj, err = s.getFromUnpacked(h)
		if err == plumbing.ErrObjectNotFound {
			obj, err = s.getFromPackfile(h, false)
		}
	}

	// If the error is still object not found, check if it's a shared object
	// repository.
	if err == plumbing.ErrObjectNotFound {
		dotgits, e := s.dir.Alternates()
		if e == nil {
			// Create a new object storage with the DotGit(s) and check for the
			// required hash object. Skip when not found.
			for _, dg := range dotgits {
				o := NewObjectStorage(dg, s.objectCache)
				enobj, enerr := o.EncodedObject(t, h)
				if enerr != nil {
					continue
				}
				return enobj, nil
			}
		}
	}

	if err != nil {
		return nil, err
	}

	if plumbing.AnyObject != t && obj.Type() != t {
		return nil, plumbing.ErrObjectNotFound
	}

	return obj, nil
}

I'm wondering if this is a bug or if I'm going about the wrong way to checkout by tag.

3DA1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0