Skip to content

Commit 203a66b

Browse files
committed
Recursing into parent commits but not submodules.
1 parent 4990f7e commit 203a66b

File tree

1 file changed

+75
-23
lines changed

1 file changed

+75
-23
lines changed

subtrac.go

Lines changed: 75 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
// "github.com/pborman/getopt/v2"
66
"gopkg.in/src-d/go-git.v4"
77
"gopkg.in/src-d/go-git.v4/plumbing"
8+
"gopkg.in/src-d/go-git.v4/plumbing/filemode"
89
"gopkg.in/src-d/go-git.v4/plumbing/object"
910
"log"
1011
"strings"
@@ -19,35 +20,36 @@ func fatalf(fmt string, args ...interface{}) {
1920
}
2021

2122
type Trac struct {
22-
commit object.Commit
23-
subHeads []Trac
23+
name string
24+
hash plumbing.Hash
25+
subHeads []*Trac
2426
tracCommit *object.Commit
2527
}
2628

2729
func (t Trac) String() string {
2830
var heads []string
2931
for _, v := range t.subHeads {
30-
heads = append(heads, fmt.Sprintf("%.10v", v.commit.Hash))
32+
heads = append(heads, fmt.Sprintf("%.10v", v.hash))
3133
}
3234
headstr := strings.Join(heads, ",")
3335

3436
if t.tracCommit != nil {
35-
return fmt.Sprintf("%.10v[%v]<%.10v>",
36-
t.commit.Hash, headstr, t.tracCommit.Hash)
37+
return fmt.Sprintf("%.10v:%v[%v]<%.10v>",
38+
t.hash, t.name, headstr, t.tracCommit.Hash)
3739
} else {
38-
return fmt.Sprintf("%.10v[%v]<>", t.commit.Hash, headstr)
40+
return fmt.Sprintf("%.10v:%v[%v]<>", t.hash, t.name, headstr)
3941
}
4042
}
4143

4244
type Cache struct {
4345
repo *git.Repository
44-
tracs map[plumbing.Hash]Trac
46+
tracs map[plumbing.Hash]*Trac
4547
}
4648

4749
func NewCache(r *git.Repository) *Cache {
4850
c := Cache{
4951
repo: r,
50-
tracs: make(map[plumbing.Hash]Trac),
52+
tracs: make(map[plumbing.Hash]*Trac),
5153
}
5254
return &c
5355
}
@@ -60,27 +62,77 @@ func (c *Cache) String() string {
6062
return strings.Join(out, "\n")
6163
}
6264

65+
func (c *Cache) tracByRef(refname string) (*Trac, error) {
66+
rn := plumbing.NewBranchReferenceName(refname)
67+
ref, err := c.repo.Reference(rn, true)
68+
if err != nil {
69+
return nil, err
70+
}
71+
commit, err := c.repo.CommitObject(ref.Hash())
72+
if err != nil {
73+
return nil, err
74+
}
75+
return c.tracCommit(commit)
76+
}
77+
6378
// Mercifully, git's content-addressable storage means there are never
6479
// any cycles when traversing the commit+submodule hierarchy, although the
6580
// same sub-objects may occur many times at different points in the tree.
66-
func (c *Cache) Add(commit *object.Commit) error {
67-
c.tracs[commit.Hash] = Trac{
68-
commit: *commit,
81+
func (c *Cache) tracCommit(commit *object.Commit) (*Trac, error) {
82+
trac := c.tracs[commit.Hash]
83+
if trac != nil {
84+
return trac, nil
6985
}
70-
return nil
71-
}
72-
73-
func (c *Cache) AddByRef(refname string) error {
74-
rn := plumbing.NewBranchReferenceName(refname)
75-
ref, err := c.repo.Reference(rn, true)
86+
trac = &Trac{
87+
name: "<COMMIT>",
88+
hash: commit.Hash,
89+
}
90+
tree, err := commit.Tree()
7691
if err != nil {
77-
return err
92+
return nil, fmt.Errorf("%.10v.Tree: %v", commit.Hash, err)
7893
}
79-
commit, err := c.repo.CommitObject(ref.Hash())
94+
_, err = c.tracTree("<ROOT>", tree)
8095
if err != nil {
81-
return err
96+
return nil, fmt.Errorf("%.10v.addTree: %v", commit.Hash, err)
97+
}
98+
for _, parent := range commit.ParentHashes {
99+
pc, err := c.repo.CommitObject(parent)
100+
if err != nil {
101+
return nil, fmt.Errorf("%.10v: %v", pc.Hash, err)
102+
}
103+
_, err = c.tracCommit(pc)
104+
}
105+
c.tracs[commit.Hash] = trac
106+
return trac, nil
107+
}
108+
109+
func (c *Cache) tracTree(name string, tree *object.Tree) (*Trac, error) {
110+
trac := c.tracs[tree.Hash]
111+
if trac != nil {
112+
return trac, nil
113+
}
114+
for _, e := range tree.Entries {
115+
if e.Mode == filemode.Submodule {
116+
debugf("submodule: %v/\n", e.Name)
117+
} else if e.Mode == filemode.Dir {
118+
t, err := c.repo.TreeObject(e.Hash)
119+
if err != nil {
120+
return nil, fmt.Errorf("%.10v.Tree.%.10v: %v",
121+
tree.Hash, e.Hash, err)
122+
}
123+
_, err = c.tracTree(e.Name, t)
124+
if err != nil {
125+
return nil, fmt.Errorf("%.10v.addTree: %v",
126+
t.Hash, err)
127+
}
128+
}
129+
}
130+
trac = &Trac{
131+
name: name,
132+
hash: tree.Hash,
82133
}
83-
return c.Add(commit)
134+
c.tracs[tree.Hash] = trac
135+
return trac, nil
84136
}
85137

86138
func main() {
@@ -91,9 +143,9 @@ func main() {
91143
}
92144
c := NewCache(r)
93145
refname := "junk"
94-
err = c.AddByRef(refname)
146+
_, err = c.tracByRef(refname)
95147
if err != nil {
96148
fatalf("AddByRef: %v: %v\n", refname, err)
97149
}
98-
debugf("cache:\n%v\n", c)
150+
fmt.Printf("%v\n", c)
99151
}

0 commit comments

Comments
 (0)