Skip to content

Commit

Permalink
libgit2: fix checkout logic for CheckoutBranch
Browse files Browse the repository at this point in the history
Use the target commit, to checkout tree and set the head to the desired
branch instead of doing a hard reset to the target commit.

Signed-off-by: Sanskar Jaiswal <[email protected]>
  • Loading branch information
aryan9600 committed May 31, 2022
1 parent fe31ff9 commit f6a2024
Showing 1 changed file with 30 additions and 5 deletions.
35 changes: 30 additions & 5 deletions pkg/git/libgit2/checkout.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,19 +161,44 @@ func (c *CheckoutBranch) Checkout(ctx context.Context, path, url string, opts *g
}
defer upstreamCommit.Free()

// Once the index has been updated with Fetch, and we know the tip commit,
// a hard reset can be used to align the local worktree with the remote branch's.
err = repo.ResetToCommit(upstreamCommit, git2go.ResetHard, &git2go.CheckoutOptions{
localBranch, err := repo.LookupBranch(c.Branch, git2go.BranchLocal)
if err != nil {
// We ignore the error if the branch is not found since we are going to
// create it ourselves.
if !git2go.IsErrorCode(err, git2go.ErrorCodeNotFound) {
return nil, fmt.Errorf("cannot lookup branch '%s': %w", c.Branch, err)
}
localBranch, err = repo.CreateBranch(c.Branch, upstreamCommit, false)
if err != nil {
return nil, fmt.Errorf("cannot create local branch '%s': %w", c.Branch, err)
}
}
defer localBranch.Free()

tree, err := repo.LookupTree(upstreamCommit.TreeId())
if err != nil {
return nil, fmt.Errorf("cannot lookup tree for branch '%s': %w", c.Branch, err)
}
defer tree.Free()

err = repo.CheckoutTree(tree, &git2go.CheckoutOpts{
// the remote branch should take precedence if it exists at this point in time.
Strategy: git2go.CheckoutForce,
})
if err != nil {
return nil, fmt.Errorf("unable to hard reset to commit for '%s': %w", managed.EffectiveURL(url), gitutil.LibGit2Error(err))
return nil, fmt.Errorf("cannot checkout tree for branch '%s': %w", c.Branch, err)
}

// Set the current head to point to the requested branch.
err = repo.SetHead("refs/heads/" + c.Branch)
if err != nil {
return nil, fmt.Errorf("cannot set HEAD to branch '%s':%w", c.Branch, err)
}

// Use the current worktree's head as reference for the commit to be returned.
head, err := repo.Head()
if err != nil {
return nil, fmt.Errorf("git resolve HEAD error: %w", err)
return nil, fmt.Errorf("cannot resolve HEAD: %w", err)
}
defer head.Free()

Expand Down

0 comments on commit f6a2024

Please sign in to comment.