go-git checkout failing with reference not found

1.3k views Asked by At

I'm just starting to use the go-git library and so far it looks very promising. However, I'm trying to do a basic checkout of an existing branch and it is failing with "reference not found". I have a simple repository, with several branches but one is "main" and another is "testoffmain". Cloning, pulling and fetching the github repo work without issues.

Getting a hash for the branch seems to work fine as well:

        repo, err := git.PlainOpen(localGitRepo)
        w, err := repo.Worktree()

// Clone, Fetch, Pull all work, when I'm on the main branch

        headRef, err := repo.Head()
    newHashRef := plumbing.NewHashReference("refs/heads/testoffmain", headRef.Hash())
    hashRef := plumbing.NewHash(newHashRef.String())
    fmt.Printf("HashRef: %s", hashRef.String())   // Successfully displays the hash

        // Returns a valid hash
    revision := "origin/testoffmain"
    revHash, err := repo.ResolveRevision(plumbing.Revision(revision))
    fmt.Printf("HashRef: %s\n", revHash.String())

        // Checkout fails with "reference not found"
    referenceName := plumbing.ReferenceName("refs/heads/testoffmain")
    err = w.Checkout(&git.CheckoutOptions{
        Branch: referenceName,
        Force:  true})
    if err != nil {
        fmt.Printf("%s:  Checkout: Cound not open local repository, Error: %s\n", project.LocalRepo, err)
        return err
    }

I've search around, and oddly can't find this simple usecase, so I'm assuming I'm doing something basic wrong. I'm using github.com/go-git/go-git/v5 v5.5.2

I've tried a variety of options in

   referenceName := plumbing.ReferenceName("refs/heads/testoffmain")
   referenceName := plumbing.ReferenceName("testoffmain")
   referenceName := plumbing.ReferenceName("origin/testoffmain")
   referenceName := plumbing.ReferenceName("refs/origin/testoffmain")
   referenceName := plumbing.ReferenceName("refs/remotes/origin/testoffmain")
   referenceName := plumbing.ReferenceName("refs/remotes/testoffmain")

As I test, I tried copying .git/refs/remote/origin/testoffmain to .git/refs/head/testoffmain and I can the checkout to work, but then other issues occur.

1

There are 1 answers

2
Mukund Sharma On

You can list the referenceNames as below:

    refs, _ := r.References()
    refs.ForEach(func(ref *plumbing.Reference) error {
        if ref.Type() == plumbing.HashReference {
           fmt.Println(ref)
        }

        return nil
    })

See official link.

And then we can use it for checkout:

    w, err := r.Worktree()
    if err != nil {
        fmt.Println(err)
    }
    err = w.Checkout(&git.CheckoutOptions{
        Branch: plumbing.ReferenceName("refs/remotes/origin/" + branchName),
    })
    if err != nil {
        fmt.Println(err, branchName)
    }

where branchName is the name of the git branch you want to switch