Files
simplegit/gitcmd/tree.go
T
2026-07-15 11:06:48 -04:00

94 lines
1.7 KiB
Go

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
}