Skip to content
This repository was archived by the owner on Sep 11, 2020. It is now read-only.

Commit 180de1e

Browse files
committed
DiffTree based on TreeWalker
1 parent 57f7a36 commit 180de1e

File tree

5 files changed

+190
-77
lines changed

5 files changed

+190
-77
lines changed

cshared/tree_cshared.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,18 @@ func c_NewTreeWalker(r uint64, t uint64) uint64 {
106106
}
107107

108108
//export c_TreeWalker_Next
109-
func c_TreeWalker_Next(tw uint64) (*C.char, *C.char, uint32, *C.char,
110-
uint64, int, *C.char) {
109+
func c_TreeWalker_Next(tw uint64) (*C.char, *C.char, uint32, *C.char, int, *C.char) {
111110
obj, ok := GetObject(Handle(tw))
112111
if !ok {
113-
return nil, nil, 0, nil, IH, ErrorCodeNotFound, C.CString(MessageNotFound)
112+
return nil, nil, 0, nil, ErrorCodeNotFound, C.CString(MessageNotFound)
114113
}
115114
walker := obj.(*git.TreeWalker)
116-
name, entry, object, err := walker.Next()
115+
name, entry, err := walker.Next()
117116
if err != nil {
118-
return nil, nil, 0, nil, IH, ErrorCodeInternal, C.CString(err.Error())
117+
return nil, nil, 0, nil, ErrorCodeInternal, C.CString(err.Error())
119118
}
120119
return C.CString(name), C.CString(entry.Name), uint32(entry.Mode),
121-
CBytes(entry.Hash[:]), uint64(RegisterObject(&object)),
122-
ErrorCodeSuccess, nil
120+
CBytes(entry.Hash[:]), ErrorCodeSuccess, nil
123121
}
124122

125123
//export c_TreeWalker_Tree
@@ -140,4 +138,4 @@ func c_TreeWalker_Close(tw uint64) {
140138
}
141139
walker := obj.(*git.TreeWalker)
142140
walker.Close()
143-
}
141+
}

file.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ type File struct {
1616
Blob
1717
}
1818

19-
func newFile(name string, m os.FileMode, b *Blob) *File {
19+
// NewFile returns a File based on the given blob object
20+
func NewFile(name string, m os.FileMode, b *Blob) *File {
2021
return &File{Name: name, Mode: m, Blob: *b}
2122
}
2223

@@ -77,7 +78,7 @@ func (iter *FileIter) Next() (*File, error) {
7778
return nil, err
7879
}
7980

80-
return newFile(name, entry.Mode, blob), nil
81+
return NewFile(name, entry.Mode, blob), nil
8182
}
8283
}
8384

tree.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func (t *Tree) File(path string) (*File, error) {
6262
blob := &Blob{}
6363
blob.Decode(obj)
6464

65-
return newFile(path, e.Mode, blob), nil
65+
return NewFile(path, e.Mode, blob), nil
6666
}
6767

6868
func (t *Tree) findEntry(path string) (*TreeEntry, error) {

tree_diff.go

Lines changed: 78 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,54 @@ const (
3333

3434
type Change struct {
3535
Action
36-
Name string
37-
Files [2]*File
36+
From ChangeEntry
37+
To ChangeEntry
38+
}
39+
40+
type ChangeEntry struct {
41+
Name string
42+
Tree *Tree
43+
TreeEntry TreeEntry
44+
}
45+
46+
func (c *Change) Files() (from *File, to *File, err error) {
47+
if c.Action == Insert || c.Action == Modify {
48+
to, err = newFileFromTreeEntry(c.To.Tree, &c.To.TreeEntry)
49+
if err != nil {
50+
return
51+
}
52+
53+
}
54+
55+
if c.Action == Delete || c.Action == Modify {
56+
from, err = newFileFromTreeEntry(c.From.Tree, &c.From.TreeEntry)
57+
if err != nil {
58+
return
59+
}
60+
}
61+
62+
return
63+
}
64+
65+
func newFileFromTreeEntry(t *Tree, e *TreeEntry) (*File, error) {
66+
blob, err := t.r.Blob(e.Hash)
67+
if err != nil {
68+
return nil, err
69+
}
70+
71+
return NewFile(e.Name, e.Mode, blob), nil
3872
}
3973

4074
func (c *Change) String() string {
41-
return fmt.Sprintf("<Action: %s, Path: %s>", c.Action, c.Name)
75+
return fmt.Sprintf("<Action: %s, Path: %s>", c.Action, c.name())
76+
}
77+
78+
func (c *Change) name() string {
79+
if c.From.Name != "" {
80+
return c.From.Name
81+
}
82+
83+
return c.To.Name
4284
}
4385

4486
type Changes []*Change
@@ -68,7 +110,7 @@ func (c Changes) Swap(i, j int) {
68110
}
69111

70112
func (c Changes) Less(i, j int) bool {
71-
return strings.Compare(c[i].Name, c[j].Name) < 0
113+
return strings.Compare(c[i].name(), c[j].name()) < 0
72114
}
73115

74116
func (c Changes) String() string {
@@ -98,29 +140,34 @@ func newWithEmpty(a, b *Tree) (Changes, error) {
98140
tree = a
99141
}
100142

101-
iter := tree.Files()
102-
defer iter.Close()
143+
w := NewTreeWalker(tree.r, tree)
144+
defer w.Close()
103145

104146
for {
105-
file, err := iter.Next()
147+
path, entry, err := w.Next()
106148
if err == io.EOF {
107149
break
108150
} else if err != nil {
109151
return nil, fmt.Errorf("cannot get next file: %s", err)
110152
}
111153

112-
var files [2]*File
154+
if entry.Mode.IsDir() {
155+
continue
156+
}
157+
158+
c := &Change{Action: action}
159+
113160
if action == Insert {
114-
files[1] = file
161+
c.To.Name = path
162+
c.To.TreeEntry = entry
163+
c.To.Tree = tree
115164
} else {
116-
files[0] = file
165+
c.From.Name = path
166+
c.From.TreeEntry = entry
167+
c.From.Tree = tree
117168
}
118169

119-
changes = append(changes, &Change{
120-
Action: action,
121-
Name: file.Name,
122-
Files: files,
123-
})
170+
changes = append(changes, c)
124171
}
125172

126173
return changes, nil
@@ -146,19 +193,16 @@ func newDiffTree(a, b *Tree) ([]*Change, error) {
146193
sort.Sort(bChanges)
147194

148195
for len(aChanges) > 0 && len(bChanges) > 0 {
149-
switch comp := strings.Compare(aChanges[0].Name, bChanges[0].Name); {
196+
switch comp := strings.Compare(aChanges[0].name(), bChanges[0].name()); {
150197
case comp == 0: // append as "Modify" or ignore if not changed
151-
modified, err := hasChange(a, b, aChanges[0].Name)
198+
modified, err := hasChange(a, b, aChanges[0].name())
152199
if err != nil {
153200
return nil, err
154201
}
155202

156203
if modified {
157-
result = append(result, &Change{
158-
Action: Modify,
159-
Name: aChanges[0].Name,
160-
Files: [2]*File{aChanges[0].Files[0], bChanges[0].Files[1]},
161-
})
204+
c := mergeInsertAndDeleteIntoModify(aChanges[0], bChanges[0])
205+
result = append(result, c)
162206
}
163207

164208
aChanges = aChanges[1:]
@@ -180,6 +224,18 @@ func newDiffTree(a, b *Tree) ([]*Change, error) {
180224
return result, nil
181225
}
182226

227+
func mergeInsertAndDeleteIntoModify(a, b *Change) *Change {
228+
c := &Change{Action: Modify}
229+
c.From.Name = a.From.Name
230+
c.From.Tree = a.From.Tree
231+
c.From.TreeEntry = a.From.TreeEntry
232+
c.To.Name = b.To.Name
233+
c.To.Tree = b.To.Tree
234+
c.To.TreeEntry = b.To.TreeEntry
235+
236+
return c
237+
}
238+
183239
func hasChange(a, b *Tree, path string) (bool, error) {
184240
ha, err := hash(a, path)
185241
if err != nil {

0 commit comments

Comments
 (0)