libgit2 / git2go

Git to Go; bindings for libgit2. Like McDonald's but tastier.
MIT License
1.92k stars 316 forks source link

How do I checkout a branch in a similar way than the CLI does? #948

Open pablocompagni-contractorvp opened 1 year ago

pablocompagni-contractorvp commented 1 year ago

Looking at this issue it seems this should be a branch switch and then a checkout, but I just can't figure out how to do it. https://github.com/libgit2/git2go/issues/291

I've tried doing this:

func CheckoutBranch(r *git.Repository, b *git.Branch) error {
    err := r.SetHead(b.Reference.Name())
    if err != nil {
        return err
    }
    return nil
}

and this:

func CheckoutBranch(r *git.Repository, b *git.Branch) error {
    err := r.SetHead(b.Reference.Name())
    if err != nil {
        return err
    }

    return r.CheckoutHead(&git.CheckoutOptions{
        Strategy: git.CheckoutForce,
    })
}

But they both end up with a detached head. I've also tried, based on the suggestions from the other ticket, to do this:

func CheckoutBranch(r *git.Repository, b *git.Branch) error {
    err := r.SetHead(b.Reference.Name())
    if err != nil {
        return err
    }
    tree, err := r.LookupTree(b.Target())
    if err != nil {
        return err
    }

    return r.CheckoutTree(tree, &git.CheckoutOptions{
        Strategy: git.CheckoutForce,
    })
}

But this just throws and error.

liuqianhong6007 commented 1 year ago

I do this as following

func Checkout(repo *git.Repository, branch *git.Branch) error {
    branchName, err := branch.Name()
    if err != nil {
        return err
    }

    commit, err := repo.LookupCommit(branch.Target())
    if err != nil {
        return err
    }
    defer commit.Free()

    tree, err := repo.LookupTree(commit.TreeId())
    if err != nil {
        return err
    }
    defer tree.Free()

    err = repo.CheckoutTree(tree, &git.CheckoutOptions{
        Strategy: git.CheckoutForce,
    })
    if err != nil {
        return err
    }

    err = repo.SetHead("refs/heads/" + branchName)
    if err != nil {
        return err
    }
    return nil
}