@@ -107,7 +107,12 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
107107 return ErrDeleteRefNotSupported
108108 }
109109
110- req , err := r .newReferenceUpdateRequest (o , remoteRefs , ar )
110+ localRefs , err := r .references ()
111+ if err != nil {
112+ return err
113+ }
114+
115+ req , err := r .newReferenceUpdateRequest (o , localRefs , remoteRefs , ar )
111116 if err != nil {
112117 return err
113118 }
@@ -156,7 +161,12 @@ func (r *Remote) PushContext(ctx context.Context, o *PushOptions) error {
156161 return r .updateRemoteReferenceStorage (req , rs )
157162}
158163
159- func (r * Remote ) newReferenceUpdateRequest (o * PushOptions , remoteRefs storer.ReferenceStorer , ar * packp.AdvRefs ) (* packp.ReferenceUpdateRequest , error ) {
164+ func (r * Remote ) newReferenceUpdateRequest (
165+ o * PushOptions ,
166+ localRefs []* plumbing.Reference ,
167+ remoteRefs storer.ReferenceStorer ,
168+ ar * packp.AdvRefs ,
169+ ) (* packp.ReferenceUpdateRequest , error ) {
160170 req := packp .NewReferenceUpdateRequestFromCapabilities (ar .Capabilities )
161171
162172 if o .Progress != nil {
@@ -168,7 +178,7 @@ func (r *Remote) newReferenceUpdateRequest(o *PushOptions, remoteRefs storer.Ref
168178 }
169179 }
170180
171- if err := r .addReferencesToUpdate (o .RefSpecs , remoteRefs , req ); err != nil {
181+ if err := r .addReferencesToUpdate (o .RefSpecs , localRefs , remoteRefs , req ); err != nil {
172182 return nil , err
173183 }
174184
@@ -262,14 +272,19 @@ func (r *Remote) fetch(ctx context.Context, o *FetchOptions) (storer.ReferenceSt
262272 return nil , err
263273 }
264274
275+ localRefs , err := r .references ()
276+ if err != nil {
277+ return nil , err
278+ }
279+
265280 refs , err := calculateRefs (o .RefSpecs , remoteRefs , o .Tags )
266281 if err != nil {
267282 return nil , err
268283 }
269284
270285 req .Wants , err = getWants (r .s , refs )
271286 if len (req .Wants ) > 0 {
272- req .Haves , err = getHaves (r . s )
287+ req .Haves , err = getHaves (localRefs )
273288 if err != nil {
274289 return nil , err
275290 }
@@ -346,17 +361,18 @@ func (r *Remote) fetchPack(ctx context.Context, o *FetchOptions, s transport.Upl
346361 return err
347362}
348363
349- func (r * Remote ) addReferencesToUpdate (refspecs []config.RefSpec ,
364+ func (r * Remote ) addReferencesToUpdate (
365+ refspecs []config.RefSpec ,
366+ localRefs []* plumbing.Reference ,
350367 remoteRefs storer.ReferenceStorer ,
351368 req * packp.ReferenceUpdateRequest ) error {
352-
353369 for _ , rs := range refspecs {
354370 if rs .IsDelete () {
355371 if err := r .deleteReferences (rs , remoteRefs , req ); err != nil {
356372 return err
357373 }
358374 } else {
359- if err := r .addOrUpdateReferences (rs , remoteRefs , req ); err != nil {
375+ if err := r .addOrUpdateReferences (rs , localRefs , remoteRefs , req ); err != nil {
360376 return err
361377 }
362378 }
@@ -365,18 +381,20 @@ func (r *Remote) addReferencesToUpdate(refspecs []config.RefSpec,
365381 return nil
366382}
367383
368- func (r * Remote ) addOrUpdateReferences (rs config.RefSpec ,
369- remoteRefs storer.ReferenceStorer , req * packp.ReferenceUpdateRequest ) error {
370- iter , err := r .s .IterReferences ()
371- if err != nil {
372- return err
384+ func (r * Remote ) addOrUpdateReferences (
385+ rs config.RefSpec ,
386+ localRefs []* plumbing.Reference ,
387+ remoteRefs storer.ReferenceStorer ,
388+ req * packp.ReferenceUpdateRequest ,
389+ ) error {
390+ for _ , ref := range localRefs {
391+ err := r .addReferenceIfRefSpecMatches (rs , remoteRefs , ref , req )
392+ if err != nil {
393+ return err
394+ }
373395 }
374396
375- return iter .ForEach (func (ref * plumbing.Reference ) error {
376- return r .addReferenceIfRefSpecMatches (
377- rs , remoteRefs , ref , req ,
378- )
379- })
397+ return nil
380398}
381399
382400func (r * Remote ) deleteReferences (rs config.RefSpec ,
@@ -449,28 +467,41 @@ func (r *Remote) addReferenceIfRefSpecMatches(rs config.RefSpec,
449467 return nil
450468}
451469
452- func getHaves (localRefs storer.ReferenceStorer ) ([]plumbing.Hash , error ) {
453- iter , err := localRefs .IterReferences ()
470+ func (r * Remote ) references () ([]* plumbing.Reference , error ) {
471+ var localRefs []* plumbing.Reference
472+ iter , err := r .s .IterReferences ()
454473 if err != nil {
455474 return nil , err
456475 }
457476
477+ for {
478+ ref , err := iter .Next ()
479+ if err == io .EOF {
480+ break
481+ }
482+
483+ if err != nil {
484+ return nil , err
485+ }
486+
487+ localRefs = append (localRefs , ref )
488+ }
489+
490+ return localRefs , nil
491+ }
492+
493+ func getHaves (localRefs []* plumbing.Reference ) ([]plumbing.Hash , error ) {
458494 haves := map [plumbing.Hash ]bool {}
459- err = iter . ForEach ( func ( ref * plumbing. Reference ) error {
495+ for _ , ref := range localRefs {
460496 if haves [ref .Hash ()] == true {
461- return nil
497+ continue
462498 }
463499
464500 if ref .Type () != plumbing .HashReference {
465- return nil
501+ continue
466502 }
467503
468504 haves [ref .Hash ()] = true
469- return nil
470- })
471-
472- if err != nil {
473- return nil , err
474505 }
475506
476507 var result []plumbing.Hash
0 commit comments