git2go icon indicating copy to clipboard operation
git2go copied to clipboard

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

Open pablocompagni-contractorvp opened this issue 1 year ago • 1 comments

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.

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
}

liuqianhong6007 avatar Mar 13 '23 06:03 liuqianhong6007