Skip to content

Commit

Permalink
Merge pull request #966 from aymanbagabas/taghash-checkout
Browse files Browse the repository at this point in the history
git: worktree checkout tag hash id (#959)
  • Loading branch information
pjbgf committed Dec 14, 2023
2 parents c8348a6 + 1e2b0d6 commit 02bed28
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 17 deletions.
6 changes: 3 additions & 3 deletions options.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,9 +324,9 @@ var (

// CheckoutOptions describes how a checkout operation should be performed.
type CheckoutOptions struct {
// Hash is the hash of the commit to be checked out. If used, HEAD will be
// in detached mode. If Create is not used, Branch and Hash are mutually
// exclusive.
// Hash is the hash of a commit or tag to be checked out. If used, HEAD
// will be in detached mode. If Create is not used, Branch and Hash are
// mutually exclusive.
Hash plumbing.Hash
// Branch to be checked out, if Branch and Hash are empty is set to `master`.
Branch plumbing.ReferenceName
Expand Down
23 changes: 10 additions & 13 deletions worktree.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,36 +227,33 @@ func (w *Worktree) createBranch(opts *CheckoutOptions) error {
}

func (w *Worktree) getCommitFromCheckoutOptions(opts *CheckoutOptions) (plumbing.Hash, error) {
if !opts.Hash.IsZero() {
return opts.Hash, nil
}

b, err := w.r.Reference(opts.Branch, true)
if err != nil {
return plumbing.ZeroHash, err
}
hash := opts.Hash
if hash.IsZero() {
b, err := w.r.Reference(opts.Branch, true)
if err != nil {
return plumbing.ZeroHash, err
}

if !b.Name().IsTag() {
return b.Hash(), nil
hash = b.Hash()
}

o, err := w.r.Object(plumbing.AnyObject, b.Hash())
o, err := w.r.Object(plumbing.AnyObject, hash)
if err != nil {
return plumbing.ZeroHash, err
}

switch o := o.(type) {
case *object.Tag:
if o.TargetType != plumbing.CommitObject {
return plumbing.ZeroHash, fmt.Errorf("unsupported tag object target %q", o.TargetType)
return plumbing.ZeroHash, fmt.Errorf("%w: tag target %q", object.ErrUnsupportedObject, o.TargetType)
}

return o.Target, nil
case *object.Commit:
return o.Hash, nil
}

return plumbing.ZeroHash, fmt.Errorf("unsupported tag target %q", o.Type())
return plumbing.ZeroHash, fmt.Errorf("%w: %q", object.ErrUnsupportedObject, o.Type())
}

func (w *Worktree) setHEADToCommit(commit plumbing.Hash) error {
Expand Down
2 changes: 1 addition & 1 deletion worktree_commit.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,4 +263,4 @@ func (h *buildTreeHelper) copyTreeToStorageRecursive(parent string, t *object.Tr
return hash, nil
}
return h.s.SetEncodedObject(o)
}
}
35 changes: 35 additions & 0 deletions worktree_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -886,6 +886,41 @@ func (s *WorktreeSuite) TestCheckoutTag(c *C) {
c.Assert(head.Name().String(), Equals, "HEAD")
}

func (s *WorktreeSuite) TestCheckoutTagHash(c *C) {
f := fixtures.ByTag("tags").One()
r := s.NewRepositoryWithEmptyWorktree(f)
w, err := r.Worktree()
c.Assert(err, IsNil)

for _, hash := range []string{
"b742a2a9fa0afcfa9a6fad080980fbc26b007c69", // annotated tag
"ad7897c0fb8e7d9a9ba41fa66072cf06095a6cfc", // commit tag
"f7b877701fbf855b44c0a9e86f3fdce2c298b07f", // lightweight tag
} {
err = w.Checkout(&CheckoutOptions{
Hash: plumbing.NewHash(hash),
})
c.Assert(err, IsNil)
head, err := w.r.Head()
c.Assert(err, IsNil)
c.Assert(head.Name().String(), Equals, "HEAD")

status, err := w.Status()
c.Assert(err, IsNil)
c.Assert(status.IsClean(), Equals, true)
}

for _, hash := range []string{
"fe6cb94756faa81e5ed9240f9191b833db5f40ae", // blob tag
"152175bf7e5580299fa1f0ba41ef6474cc043b70", // tree tag
} {
err = w.Checkout(&CheckoutOptions{
Hash: plumbing.NewHash(hash),
})
c.Assert(err, NotNil)
}
}

func (s *WorktreeSuite) TestCheckoutBisect(c *C) {
if testing.Short() {
c.Skip("skipping test in short mode.")
Expand Down

0 comments on commit 02bed28

Please sign in to comment.