diff options
author | Paulo Gomes <pjbgf@linux.com> | 2023-12-14 09:22:18 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-12-14 09:22:18 +0000 |
commit | 02bed284891e49ff594354101c897a29af3dbb43 (patch) | |
tree | d57b186e078d2d253304fc4784ed3d207d3b7e4c | |
parent | c8348a650177cb0fbb9ef3d0551b5a969c6b4ac3 (diff) | |
parent | 1e2b0d67ae859dc3c81fc4455290287235395d09 (diff) | |
download | go-git-02bed284891e49ff594354101c897a29af3dbb43.tar.gz |
Merge pull request #966 from aymanbagabas/taghash-checkout
git: worktree checkout tag hash id (#959)
-rw-r--r-- | options.go | 6 | ||||
-rw-r--r-- | worktree.go | 23 | ||||
-rw-r--r-- | worktree_commit.go | 2 | ||||
-rw-r--r-- | worktree_test.go | 35 |
4 files changed, 49 insertions, 17 deletions
@@ -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 diff --git a/worktree.go b/worktree.go index ad525c1..4dfe036 100644 --- a/worktree.go +++ b/worktree.go @@ -227,20 +227,17 @@ 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 } @@ -248,7 +245,7 @@ func (w *Worktree) getCommitFromCheckoutOptions(opts *CheckoutOptions) (plumbing 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 @@ -256,7 +253,7 @@ func (w *Worktree) getCommitFromCheckoutOptions(opts *CheckoutOptions) (plumbing 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 { diff --git a/worktree_commit.go b/worktree_commit.go index eaa21c3..4d811f3 100644 --- a/worktree_commit.go +++ b/worktree_commit.go @@ -263,4 +263,4 @@ func (h *buildTreeHelper) copyTreeToStorageRecursive(parent string, t *object.Tr return hash, nil } return h.s.SetEncodedObject(o) -}
\ No newline at end of file +} diff --git a/worktree_test.go b/worktree_test.go index 50ff189..5759ec4 100644 --- a/worktree_test.go +++ b/worktree_test.go @@ -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.") |