git-module

git clone git://git.lin.moe/fork/git-module.git

 1package git
 2
 3import (
 4	"context"
 5	"strings"
 6	"sync"
 7)
 8
 9// Tree represents a flat directory listing in Git.
10type Tree struct {
11	id     Oid
12	parent *Tree
13
14	repo *Repository
15
16	entries    Entries
17	entriesMu  sync.Mutex
18	entriesSet bool
19}
20
21// Subtree returns a subtree by given subpath of the tree.
22func (t *Tree) Subtree(ctx context.Context, subpath string, opts ...LsTreeOptions) (*Tree, error) {
23	if len(subpath) == 0 {
24		return t, nil
25	}
26
27	paths := strings.Split(subpath, "/")
28	var (
29		err error
30		g   = t
31		p   = t
32		e   *TreeEntry
33	)
34	for _, name := range paths {
35		e, err = p.TreeEntry(ctx, name, opts...)
36		if err != nil {
37			return nil, err
38		}
39
40		g = &Tree{
41			id:     e.id,
42			parent: p,
43			repo:   t.repo,
44		}
45		p = g
46	}
47	return g, nil
48}
49
50// Entries returns all entries of the tree. Successful results are cached;
51// failed attempts are not cached, allowing retries with a fresh context.
52func (t *Tree) Entries(ctx context.Context, opts ...LsTreeOptions) (Entries, error) {
53	t.entriesMu.Lock()
54	defer t.entriesMu.Unlock()
55
56	if t.entriesSet {
57		return t.entries, nil
58	}
59
60	tt, err := t.repo.LsTree(ctx, t.id.String(), opts...)
61	if err != nil {
62		return nil, err
63	}
64	t.entries = tt.entries
65	t.entriesSet = true
66	return t.entries, nil
67}