@@ -134,7 +134,7 @@ func (r *Remote) Push(o *PushOptions) (err error) {
134
134
return rs .Error ()
135
135
}
136
136
137
- func (r * Remote ) fetch (o * FetchOptions ) (refs storer.ReferenceStorer , err error ) {
137
+ func (r * Remote ) fetch (o * FetchOptions ) (storer.ReferenceStorer , error ) {
138
138
if o .RemoteName == "" {
139
139
o .RemoteName = r .c .Name
140
140
}
@@ -169,7 +169,12 @@ func (r *Remote) fetch(o *FetchOptions) (refs storer.ReferenceStorer, err error)
169
169
return nil , err
170
170
}
171
171
172
- req .Wants , err = getWants (o .RefSpecs , r .s , remoteRefs )
172
+ refs , err := calculateRefs (o .RefSpecs , remoteRefs , o .Tags )
173
+ if err != nil {
174
+ return nil , err
175
+ }
176
+
177
+ req .Wants , err = getWants (r .s , refs )
173
178
if len (req .Wants ) > 0 {
174
179
req .Haves , err = getHaves (r .s )
175
180
if err != nil {
@@ -181,14 +186,15 @@ func (r *Remote) fetch(o *FetchOptions) (refs storer.ReferenceStorer, err error)
181
186
}
182
187
}
183
188
184
- err = r .updateLocalReferenceStorage (o .RefSpecs , remoteRefs )
185
- if err != nil && err != NoErrAlreadyUpToDate {
189
+ updated , err : = r .updateLocalReferenceStorage (o .RefSpecs , refs , remoteRefs )
190
+ if err != nil {
186
191
return nil , err
187
192
}
188
193
189
- if len ( req . Wants ) == 0 {
190
- return remoteRefs , err
194
+ if ! updated {
195
+ return remoteRefs , NoErrAlreadyUpToDate
191
196
}
197
+
192
198
return remoteRefs , nil
193
199
}
194
200
@@ -382,56 +388,52 @@ func getHaves(localRefs storer.ReferenceStorer) ([]plumbing.Hash, error) {
382
388
return result , nil
383
389
}
384
390
385
- func getWants (
386
- spec []config.RefSpec , localStorer storage.Storer , remoteRefs storer.ReferenceStorer ,
387
- ) ([]plumbing.Hash , error ) {
388
- wantTags := true
389
- for _ , s := range spec {
390
- if ! s .IsWildcard () {
391
- wantTags = false
392
- break
393
- }
394
- }
395
-
391
+ func calculateRefs (spec []config.RefSpec ,
392
+ remoteRefs storer.ReferenceStorer ,
393
+ tags TagFetchMode ,
394
+ ) (memory.ReferenceStorage , error ) {
396
395
iter , err := remoteRefs .IterReferences ()
397
396
if err != nil {
398
397
return nil , err
399
398
}
400
399
401
- wants := map [plumbing. Hash ] bool {}
402
- err = iter .ForEach (func (ref * plumbing.Reference ) error {
400
+ refs := make (memory. ReferenceStorage , 0 )
401
+ return refs , iter .ForEach (func (ref * plumbing.Reference ) error {
403
402
if ! config .MatchAny (spec , ref .Name ()) {
404
- if ! ref .IsTag () || ! wantTags {
403
+ if ! ref .IsTag () || tags != AllTags {
405
404
return nil
406
405
}
407
406
}
408
407
409
408
if ref .Type () == plumbing .SymbolicReference {
410
- ref , err = storer .ResolveReference (remoteRefs , ref .Name ())
409
+ target , err : = storer .ResolveReference (remoteRefs , ref .Name ())
411
410
if err != nil {
412
411
return err
413
412
}
413
+
414
+ ref = plumbing .NewHashReference (ref .Name (), target .Hash ())
414
415
}
415
416
416
417
if ref .Type () != plumbing .HashReference {
417
418
return nil
418
419
}
419
420
420
- hash := ref .Hash ()
421
+ return refs .SetReference (ref )
422
+ })
423
+ }
421
424
422
- exists , err := objectExists (localStorer , hash )
425
+ func getWants (localStorer storage.Storer , refs memory.ReferenceStorage ) ([]plumbing.Hash , error ) {
426
+ wants := map [plumbing.Hash ]bool {}
427
+ for _ , ref := range refs {
428
+ hash := ref .Hash ()
429
+ exists , err := objectExists (localStorer , ref .Hash ())
423
430
if err != nil {
424
- return err
431
+ return nil , err
425
432
}
426
433
427
434
if ! exists {
428
435
wants [hash ] = true
429
436
}
430
-
431
- return nil
432
- })
433
- if err != nil {
434
- return nil , err
435
437
}
436
438
437
439
var result []plumbing.Hash
@@ -513,6 +515,19 @@ func (r *Remote) newUploadPackRequest(o *FetchOptions,
513
515
}
514
516
}
515
517
518
+ isWildcard := true
519
+ for _ , s := range o .RefSpecs {
520
+ if ! s .IsWildcard () {
521
+ isWildcard = false
522
+ }
523
+ }
524
+
525
+ if isWildcard && o .Tags == TagFollowing && ar .Capabilities .Supports (capability .IncludeTag ) {
526
+ if err := req .Capabilities .Set (capability .IncludeTag ); err != nil {
527
+ return nil , err
528
+ }
529
+ }
530
+
516
531
return req , nil
517
532
}
518
533
@@ -534,10 +549,17 @@ func buildSidebandIfSupported(l *capability.List, reader io.Reader, p sideband.P
534
549
return d
535
550
}
536
551
537
- func (r * Remote ) updateLocalReferenceStorage (specs []config.RefSpec , refs memory.ReferenceStorage ) error {
538
- updated := false
552
+ func (r * Remote ) updateLocalReferenceStorage (
553
+ specs []config.RefSpec ,
554
+ fetchedRefs , remoteRefs memory.ReferenceStorage ,
555
+ ) (updated bool , err error ) {
556
+ isWildcard := true
539
557
for _ , spec := range specs {
540
- for _ , ref := range refs {
558
+ if ! spec .IsWildcard () {
559
+ isWildcard = false
560
+ }
561
+
562
+ for _ , ref := range fetchedRefs {
541
563
if ! spec .Match (ref .Name ()) {
542
564
continue
543
565
}
@@ -546,33 +568,36 @@ func (r *Remote) updateLocalReferenceStorage(specs []config.RefSpec, refs memory
546
568
continue
547
569
}
548
570
549
- name := spec .Dst (ref .Name ())
550
- sref , err := r .s .Reference (name )
551
- if err != nil && err != plumbing .ErrReferenceNotFound {
552
- return err
571
+ new := plumbing .NewHashReference (spec .Dst (ref .Name ()), ref .Hash ())
572
+
573
+ refUpdated , err := updateReferenceStorerIfNeeded (r .s , new )
574
+ if err != nil {
575
+ return updated , err
553
576
}
554
- if err == plumbing .ErrReferenceNotFound || sref .Hash () != ref .Hash () {
555
- n := plumbing .NewHashReference (name , ref .Hash ())
556
- if err := r .s .SetReference (n ); err != nil {
557
- return err
558
- }
577
+
578
+ if refUpdated {
559
579
updated = true
560
580
}
561
581
}
562
582
}
563
583
564
- if err := r .buildFetchedTags (refs ); err != nil {
565
- return err
584
+ tags := fetchedRefs
585
+ if isWildcard {
586
+ tags = remoteRefs
587
+ }
588
+ tagUpdated , err := r .buildFetchedTags (tags )
589
+ if err != nil {
590
+ return updated , err
566
591
}
567
592
568
- if ! updated {
569
- return NoErrAlreadyUpToDate
593
+ if tagUpdated {
594
+ updated = true
570
595
}
571
- return nil
596
+
597
+ return
572
598
}
573
599
574
- func (r * Remote ) buildFetchedTags (refs memory.ReferenceStorage ) error {
575
- updated := false
600
+ func (r * Remote ) buildFetchedTags (refs memory.ReferenceStorage ) (updated bool , err error ) {
576
601
for _ , ref := range refs {
577
602
if ! ref .IsTag () {
578
603
continue
@@ -584,18 +609,20 @@ func (r *Remote) buildFetchedTags(refs memory.ReferenceStorage) error {
584
609
}
585
610
586
611
if err != nil {
587
- return err
612
+ return false , err
588
613
}
589
614
590
- if err = r .s .SetReference (ref ); err != nil {
591
- return err
615
+ refUpdated , err := updateReferenceStorerIfNeeded (r .s , ref )
616
+ if err != nil {
617
+ return updated , err
618
+ }
619
+
620
+ if refUpdated {
621
+ updated = true
592
622
}
593
- updated = true
594
- }
595
- if ! updated {
596
- return NoErrAlreadyUpToDate
597
623
}
598
- return nil
624
+
625
+ return
599
626
}
600
627
601
628
func objectsToPush (commands []* packp.Command ) ([]plumbing.Hash , error ) {
0 commit comments