Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 51ecb54

Browse files
committed
repository: Resolve commit when cloning annotated tag, fixes #557
1 parent 2f58c82 commit 51ecb54

File tree

2 files changed

+61
-12
lines changed

2 files changed

+61
-12
lines changed

repository.go

+40-12
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,25 @@ func (r *Repository) DeleteRemote(name string) error {
400400
return r.Storer.SetConfig(cfg)
401401
}
402402

403+
func (r *Repository) resolveToCommitHash(h plumbing.Hash) (plumbing.Hash, error) {
404+
obj, err := r.Storer.EncodedObject(plumbing.AnyObject, h)
405+
if err != nil {
406+
return plumbing.ZeroHash, err
407+
}
408+
switch obj.Type() {
409+
case plumbing.TagObject:
410+
t, err := object.DecodeTag(r.Storer, obj)
411+
if err != nil {
412+
return plumbing.ZeroHash, err
413+
}
414+
return r.resolveToCommitHash(t.Target)
415+
case plumbing.CommitObject:
416+
return h, nil
417+
default:
418+
return plumbing.ZeroHash, errors.New("Unable to resolve to commit")
419+
}
420+
}
421+
403422
// Clone clones a remote repository
404423
func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
405424
if err := o.Validate(); err != nil {
@@ -415,7 +434,7 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
415434
return err
416435
}
417436

418-
head, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
437+
ref, err := r.fetchAndUpdateReferences(ctx, &FetchOptions{
419438
RefSpecs: r.cloneRefSpec(o, c),
420439
Depth: o.Depth,
421440
Auth: o.Auth,
@@ -431,6 +450,11 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
431450
return err
432451
}
433452

453+
head, err := r.Head()
454+
if err != nil {
455+
return err
456+
}
457+
434458
if err := w.Reset(&ResetOptions{Commit: head.Hash()}); err != nil {
435459
return err
436460
}
@@ -445,7 +469,7 @@ func (r *Repository) clone(ctx context.Context, o *CloneOptions) error {
445469
}
446470
}
447471

448-
return r.updateRemoteConfigIfNeeded(o, c, head)
472+
return r.updateRemoteConfigIfNeeded(o, c, ref)
449473
}
450474

451475
const (
@@ -520,12 +544,12 @@ func (r *Repository) fetchAndUpdateReferences(
520544
return nil, err
521545
}
522546

523-
head, err := storer.ResolveReference(remoteRefs, ref)
547+
resolvedRef, err := storer.ResolveReference(remoteRefs, ref)
524548
if err != nil {
525549
return nil, err
526550
}
527551

528-
refsUpdated, err := r.updateReferences(remote.c.Fetch, head)
552+
refsUpdated, err := r.updateReferences(remote.c.Fetch, resolvedRef)
529553
if err != nil {
530554
return nil, err
531555
}
@@ -534,26 +558,30 @@ func (r *Repository) fetchAndUpdateReferences(
534558
return nil, NoErrAlreadyUpToDate
535559
}
536560

537-
return head, nil
561+
return resolvedRef, nil
538562
}
539563

540564
func (r *Repository) updateReferences(spec []config.RefSpec,
541-
resolvedHead *plumbing.Reference) (updated bool, err error) {
565+
resolvedRef *plumbing.Reference) (updated bool, err error) {
542566

543-
if !resolvedHead.Name().IsBranch() {
567+
if !resolvedRef.Name().IsBranch() {
544568
// Detached HEAD mode
545-
head := plumbing.NewHashReference(plumbing.HEAD, resolvedHead.Hash())
569+
h, err := r.resolveToCommitHash(resolvedRef.Hash())
570+
if err != nil {
571+
return false, err
572+
}
573+
head := plumbing.NewHashReference(plumbing.HEAD, h)
546574
return updateReferenceStorerIfNeeded(r.Storer, head)
547575
}
548576

549577
refs := []*plumbing.Reference{
550-
// Create local reference for the resolved head
551-
resolvedHead,
578+
// Create local reference for the resolved ref
579+
resolvedRef,
552580
// Create local symbolic HEAD
553-
plumbing.NewSymbolicReference(plumbing.HEAD, resolvedHead.Name()),
581+
plumbing.NewSymbolicReference(plumbing.HEAD, resolvedRef.Name()),
554582
}
555583

556-
refs = append(refs, r.calculateRemoteHeadReference(spec, resolvedHead)...)
584+
refs = append(refs, r.calculateRemoteHeadReference(spec, resolvedRef)...)
557585

558586
for _, ref := range refs {
559587
u, err := updateReferenceStorerIfNeeded(r.Storer, ref)

repository_test.go

+21
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,27 @@ func (s *RepositorySuite) TestCloneDetachedHEADAndShallow(c *C) {
651651
c.Assert(count, Equals, 15)
652652
}
653653

654+
func (s *RepositorySuite) TestCloneDetachedHEADAnnotatedTag(c *C) {
655+
r, _ := Init(memory.NewStorage(), nil)
656+
err := r.clone(context.Background(), &CloneOptions{
657+
URL: s.GetLocalRepositoryURL(fixtures.ByTag("tags").One()),
658+
ReferenceName: plumbing.ReferenceName("refs/tags/annotated-tag"),
659+
})
660+
c.Assert(err, IsNil)
661+
662+
head, err := r.Reference(plumbing.HEAD, false)
663+
c.Assert(err, IsNil)
664+
c.Assert(head, NotNil)
665+
c.Assert(head.Type(), Equals, plumbing.HashReference)
666+
c.Assert(head.Hash().String(), Equals, "f7b877701fbf855b44c0a9e86f3fdce2c298b07f")
667+
668+
count := 0
669+
objects, err := r.Objects()
670+
c.Assert(err, IsNil)
671+
objects.ForEach(func(object.Object) error { count++; return nil })
672+
c.Assert(count, Equals, 7)
673+
}
674+
654675
func (s *RepositorySuite) TestPush(c *C) {
655676
url := c.MkDir()
656677
server, err := PlainInit(url, true)

0 commit comments

Comments
 (0)