PackRefs packs all loose refs into the packed-refs file. This implementation only works under the assumption that the view of the file system won't be updated during this operation. This strategy would not work on a general file system though, without locking each loose reference and checking it a
()
| 1067 | // When `all` is false, it would only pack refs that have already been |
| 1068 | // packed, plus all tags. |
| 1069 | func (d *DotGit) PackRefs() (err error) { |
| 1070 | // Lock packed-refs, and create it if it doesn't exist yet. |
| 1071 | f, err := d.openAndLockPackedRefs(true) |
| 1072 | if err != nil { |
| 1073 | return err |
| 1074 | } |
| 1075 | defer ioutil.CheckClose(f, &err) |
| 1076 | |
| 1077 | // Gather all refs using addRefsFromRefDir and addRefsFromPackedRefs. |
| 1078 | var refs []*plumbing.Reference |
| 1079 | seen := make(map[plumbing.ReferenceName]bool) |
| 1080 | if err = d.addRefsFromRefDir(&refs, seen); err != nil { |
| 1081 | return err |
| 1082 | } |
| 1083 | if len(refs) == 0 { |
| 1084 | // Nothing to do! |
| 1085 | return nil |
| 1086 | } |
| 1087 | numLooseRefs := len(refs) |
| 1088 | if err = d.addRefsFromPackedRefsFile(&refs, f, seen); err != nil { |
| 1089 | return err |
| 1090 | } |
| 1091 | |
| 1092 | // Write them all to a new temp packed-refs file. |
| 1093 | tmp, err := d.fs.TempFile("", tmpPackedRefsPrefix) |
| 1094 | if err != nil { |
| 1095 | return err |
| 1096 | } |
| 1097 | tmpName := tmp.Name() |
| 1098 | defer func() { |
| 1099 | ioutil.CheckClose(tmp, &err) |
| 1100 | _ = d.fs.Remove(tmpName) // don't check err, we might have renamed it |
| 1101 | }() |
| 1102 | |
| 1103 | w := bufio.NewWriter(tmp) |
| 1104 | for _, ref := range refs { |
| 1105 | _, err = w.WriteString(ref.String() + "\n") |
| 1106 | if err != nil { |
| 1107 | return err |
| 1108 | } |
| 1109 | } |
| 1110 | err = w.Flush() |
| 1111 | if err != nil { |
| 1112 | return err |
| 1113 | } |
| 1114 | |
| 1115 | // Rename the temp packed-refs file. |
| 1116 | err = d.rewritePackedRefsWhileLocked(tmp, f) |
| 1117 | if err != nil { |
| 1118 | return err |
| 1119 | } |
| 1120 | |
| 1121 | // Delete all the loose refs, while still holding the packed-refs |
| 1122 | // lock. |
| 1123 | for _, ref := range refs[:numLooseRefs] { |
| 1124 | path := d.fs.Join(".", ref.Name().String()) |
| 1125 | err = d.fs.Remove(path) |
| 1126 | if err != nil && !os.IsNotExist(err) { |
nothing calls this directly
no test coverage detected