package gitcmd import ( "strconv" "strings" ) type EntryType string const ( EntryBlob EntryType = "blob" EntryTree EntryType = "tree" ) type TreeEntry struct { Name string `json:"name"` Path string `json:"path"` Type EntryType `json:"type"` Mode string `json:"mode"` Size int64 `json:"size"` SHA string `json:"sha"` } type Tree struct { Ref string `json:"ref"` Path string `json:"path"` Entries []TreeEntry `json:"entries"` } func (r *Repository) GetTree(ref, path string) (*Tree, error) { if empty, err := r.IsEmpty(); err != nil { return nil, err } else if empty { return &Tree{Ref: ref, Path: path, Entries: []TreeEntry{}}, nil } treeRef := ref if path != "" { treeRef = ref + ":" + path } out, _, err := NewCommand("ls-tree", "-l"). AddDynamicArguments(treeRef). WithDir(r.Path). RunStdString(r.ctx) if err != nil { return nil, err } entries := make([]TreeEntry, 0) for _, line := range strings.Split(strings.TrimSpace(out), "\n") { if line == "" { continue } tabIdx := strings.IndexByte(line, '\t') if tabIdx < 0 { continue } header := strings.Fields(line[:tabIdx]) name := line[tabIdx+1:] if len(header) < 4 { continue } mode, objType, sha, sizeStr := header[0], header[1], header[2], header[3] var size int64 if sizeStr != "-" { size, _ = strconv.ParseInt(sizeStr, 10, 64) } entryPath := name if path != "" { entryPath = path + "/" + name } entries = append(entries, TreeEntry{ Name: name, Path: entryPath, Type: EntryType(objType), Mode: mode, Size: size, SHA: sha, }) } return &Tree{ Ref: ref, Path: path, Entries: entries, }, nil }