func (p *refParser) ParsePackedRefs() ([]objects.Ref, error) { r := make([]objects.Ref, 0) err := util.SafeParse(func() { for !p.EOF() { c := p.PeekByte() switch c { case '#': // if this is the first line, then it should be a comment // that says '# pack-refs with: <extention>' and <extention> // is exactly one of the items in this set: { 'peeled' }. // currently, we are just ignoring all comments. p.ReadString(token.LF) case '^': // this means the previous line is an annotated tag and the the current // line contains the commit that tag points to p.ConsumeByte('^') commit := p.ParseOid() p.ConsumeByte(token.LF) if l := len(r); l > 0 { _, oid := r[l-1].Target() //TODO: inefficient (copying): r[l-1] = objects.NewRef(r[l-1].Name(), "", oid.(*objects.ObjectId), commit) } default: oid := p.ParseOid() p.ConsumeByte(token.SP) name := p.ReadString(token.LF) r = append(r, objects.NewRef(name, "", oid, nil)) } } }) return r, err }
func Test_Sorting(t *testing.T) { refs := make([]objects.Ref, 3) refs[0] = objects.NewRef("zoo", "", nil, nil) refs[1] = objects.NewRef("yogurt", "", nil, nil) refs[2] = objects.NewRef("xavier", "", nil, nil) sort.Sort(refByName(refs)) util.Assert(t, refs[0].Name() == "xavier") util.Assert(t, refs[1].Name() == "yogurt") util.Assert(t, refs[2].Name() == "zoo") }
func (p *refParser) ParseRef() (r objects.Ref, err error) { err = util.SafeParse(func() { // is it a symbolic ref? if p.PeekString(len(markerRef)) == markerRef { p.ConsumeString(markerRef) p.ConsumeByte(token.SP) spec := p.ReadString(token.LF) r = objects.NewRef(p.name, spec, nil, nil) } else { oid := p.ParseOid() p.ConsumeByte(token.LF) r = objects.NewRef(p.name, "", oid, nil) } }) return r, err }
func (repo *DiskRepository) Refs() ([]objects.Ref, error) { // First, get all the packed refs. pr, err := repo.PackedRefs() if err != nil && !os.IsNotExist(err) { return nil, err } // Refs will be stores in a map by their symbolic name. refs := make(map[string]objects.Ref) for _, ref := range pr { refs[ref.Name()] = ref } // Now let's walk loose refs and collect them to supercede // the packed refs. It is worth it to note here that // packed refs may contain outdated references because // they are updated lazily. dir := path.Join(repo.path, "refs") err = filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { // refs are files, so... if !f.IsDir() { name := util.TrimPrefix(path, repo.path+"/") r, e := PeeledRefFromSpec(repo, name) if e != nil { return e } refs[name] = objects.NewRef(name, "", r.ObjectId(), nil) } return nil }, ) if err != nil { return nil, err } // collect the refs into a list refList := make([]objects.Ref, 0, len(refs)) for _, v := range refs { refList = append(refList, v) } sort.Sort(refByName(refList)) return refList, nil }
func (repo *DiskRepository) LooseRefs() ([]objects.Ref, error) { // TODO: figure out a way to decouple this logic repoPath := repo.path + "/" dir := path.Join(repoPath, "refs") refs := make([]objects.Ref, 0) err := filepath.Walk(dir, func(path string, f os.FileInfo, err error) error { if !f.IsDir() { name := util.TrimPrefix(path, repoPath) r, e := PeeledRefFromSpec(repo, name) if e != nil { return e } refs = append(refs, objects.NewRef(name, "", r.ObjectId(), nil)) } return nil }, ) return refs, err }