@@ -268,7 +268,7 @@ func (d *DotGit) Refs() ([]*plumbing.Reference, error) {
268268 return nil , err
269269 }
270270
271- if err := d .addRefsFromPackedRefs (& refs ); err != nil {
271+ if err := d .addRefsFromPackedRefs (& refs , seen ); err != nil {
272272 return nil , err
273273 }
274274
@@ -336,7 +336,8 @@ func (d *DotGit) RemoveRef(name plumbing.ReferenceName) error {
336336 path := d .fs .Join ("." , name .String ())
337337 _ , err := d .fs .Stat (path )
338338 if err == nil {
339- return d .fs .Remove (path )
339+ err = d .fs .Remove (path )
340+ // Drop down to remove it from the packed refs file, too.
340341 }
341342
342343 if err != nil && ! os .IsNotExist (err ) {
@@ -346,13 +347,18 @@ func (d *DotGit) RemoveRef(name plumbing.ReferenceName) error {
346347 return d .rewritePackedRefsWithoutRef (name )
347348}
348349
349- func (d * DotGit ) addRefsFromPackedRefs (refs * []* plumbing.Reference ) (err error ) {
350+ func (d * DotGit ) addRefsFromPackedRefs (refs * []* plumbing.Reference , seen map [plumbing. ReferenceName ] bool ) (err error ) {
350351 packedRefs , err := d .findPackedRefs ()
351352 if err != nil {
352353 return err
353354 }
354355
355- * refs = append (* refs , packedRefs ... )
356+ for _ , ref := range packedRefs {
357+ if ! seen [ref .Name ()] {
358+ * refs = append (* refs , ref )
359+ seen [ref .Name ()] = true
360+ }
361+ }
356362 return nil
357363}
358364
@@ -365,13 +371,30 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e
365371
366372 return err
367373 }
374+ doCloseF := true
375+ defer func () {
376+ if doCloseF {
377+ ioutil .CheckClose (f , & err )
378+ }
379+ }()
380+
381+ err = f .Lock ()
382+ if err != nil {
383+ return err
384+ }
368385
369386 // Creating the temp file in the same directory as the target file
370387 // improves our chances for rename operation to be atomic.
371388 tmp , err := d .fs .TempFile ("" , tmpPackedRefsPrefix )
372389 if err != nil {
373390 return err
374391 }
392+ doCloseTmp := true
393+ defer func () {
394+ if doCloseTmp {
395+ ioutil .CheckClose (tmp , & err )
396+ }
397+ }()
375398
376399 s := bufio .NewScanner (f )
377400 found := false
@@ -397,14 +420,21 @@ func (d *DotGit) rewritePackedRefsWithoutRef(name plumbing.ReferenceName) (err e
397420 }
398421
399422 if ! found {
400- return nil
423+ doCloseTmp = false
424+ ioutil .CheckClose (tmp , & err )
425+ if err != nil {
426+ return err
427+ }
428+ // Delete the temp file if nothing needed to be removed.
429+ return d .fs .Remove (tmp .Name ())
401430 }
402431
432+ doCloseF = false
403433 if err := f .Close (); err != nil {
404- ioutil .CheckClose (tmp , & err )
405434 return err
406435 }
407436
437+ doCloseTmp = false
408438 if err := tmp .Close (); err != nil {
409439 return err
410440 }
0 commit comments