@@ -12,72 +12,75 @@ import (
1212)
1313
1414type DiffFlag int
15+
1516const (
16- DiffFlagBinary = DiffFlag ( C .GIT_DIFF_FLAG_BINARY )
17- DiffFlagNotBinary = C .GIT_DIFF_FLAG_NOT_BINARY
18- DiffFlagValidOid = C .GIT_DIFF_FLAG_VALID_OID
17+ DiffFlagBinary DiffFlag = C .GIT_DIFF_FLAG_BINARY
18+ DiffFlagNotBinary = C .GIT_DIFF_FLAG_NOT_BINARY
19+ DiffFlagValidOid = C .GIT_DIFF_FLAG_VALID_OID
1920)
2021
2122type Delta int
23+
2224const (
23- DeltaUnmodified = Delta ( C .GIT_DELTA_UNMODIFIED )
24- DeltaAdded = C .GIT_DELTA_ADDED
25- DeltaDeleted = C .GIT_DELTA_DELETED
26- DeltaModified = C .GIT_DELTA_MODIFIED
27- DeltaRenamed = C .GIT_DELTA_RENAMED
28- DeltaCopied = C .GIT_DELTA_COPIED
29- DeltaIgnored = C .GIT_DELTA_IGNORED
30- DeltaUntracked = C .GIT_DELTA_UNTRACKED
31- DeltaTypeChange = C .GIT_DELTA_TYPECHANGE
25+ DeltaUnmodified Delta = C .GIT_DELTA_UNMODIFIED
26+ DeltaAdded = C .GIT_DELTA_ADDED
27+ DeltaDeleted = C .GIT_DELTA_DELETED
28+ DeltaModified = C .GIT_DELTA_MODIFIED
29+ DeltaRenamed = C .GIT_DELTA_RENAMED
30+ DeltaCopied = C .GIT_DELTA_COPIED
31+ DeltaIgnored = C .GIT_DELTA_IGNORED
32+ DeltaUntracked = C .GIT_DELTA_UNTRACKED
33+ DeltaTypeChange = C .GIT_DELTA_TYPECHANGE
3234)
3335
3436type DiffLineType int
37+
3538const (
36- DiffLineContext = DiffLineType ( C .GIT_DIFF_LINE_CONTEXT )
37- DiffLineAddition = C .GIT_DIFF_LINE_ADDITION
38- DiffLineDeletion = C .GIT_DIFF_LINE_DELETION
39- DiffLineContextEOFNL = C .GIT_DIFF_LINE_CONTEXT_EOFNL
40- DiffLineAddEOFNL = C .GIT_DIFF_LINE_ADD_EOFNL
41- DiffLineDelEOFNL = C .GIT_DIFF_LINE_DEL_EOFNL
39+ DiffLineContext DiffLineType = C .GIT_DIFF_LINE_CONTEXT
40+ DiffLineAddition = C .GIT_DIFF_LINE_ADDITION
41+ DiffLineDeletion = C .GIT_DIFF_LINE_DELETION
42+ DiffLineContextEOFNL = C .GIT_DIFF_LINE_CONTEXT_EOFNL
43+ DiffLineAddEOFNL = C .GIT_DIFF_LINE_ADD_EOFNL
44+ DiffLineDelEOFNL = C .GIT_DIFF_LINE_DEL_EOFNL
4245
4346 DiffLineFileHdr = C .GIT_DIFF_LINE_FILE_HDR
4447 DiffLineHunkHdr = C .GIT_DIFF_LINE_HUNK_HDR
45- DiffLineBinary = C .GIT_DIFF_LINE_BINARY
48+ DiffLineBinary = C .GIT_DIFF_LINE_BINARY
4649)
4750
4851type DiffFile struct {
49- Path string
50- Oid * Oid
51- Size int
52+ Path string
53+ Oid * Oid
54+ Size int
5255 Flags DiffFlag
53- Mode uint16
56+ Mode uint16
5457}
5558
56- func newDiffFile (file * C.git_diff_file ) * DiffFile {
59+ func newDiffFileFromC (file * C.git_diff_file ) * DiffFile {
5760 return & DiffFile {
58- Path : C .GoString (file .path ),
59- Oid : newOidFromC (& file .oid ),
60- Size : int (file .size ),
61+ Path : C .GoString (file .path ),
62+ Oid : newOidFromC (& file .oid ),
63+ Size : int (file .size ),
6164 Flags : DiffFlag (file .flags ),
62- Mode : uint16 (file .mode ),
65+ Mode : uint16 (file .mode ),
6366 }
6467}
6568
6669type DiffDelta struct {
67- Status Delta
68- Flags DiffFlag
70+ Status Delta
71+ Flags DiffFlag
6972 Similarity uint16
70- OldFile * DiffFile
71- NewFile * DiffFile
73+ OldFile * DiffFile
74+ NewFile * DiffFile
7275}
7376
74- func newDiffDelta (delta * C.git_diff_delta ) * DiffDelta {
77+ func newDiffDeltaFromC (delta * C.git_diff_delta ) * DiffDelta {
7578 return & DiffDelta {
76- Status : Delta (delta .status ),
77- Flags : DiffFlag (delta .flags ),
79+ Status : Delta (delta .status ),
80+ Flags : DiffFlag (delta .flags ),
7881 Similarity : uint16 (delta .similarity ),
79- OldFile : newDiffFile (& delta .old_file ),
80- NewFile : newDiffFile (& delta .new_file ),
82+ OldFile : newDiffFileFromC (& delta .old_file ),
83+ NewFile : newDiffFileFromC (& delta .new_file ),
8184 }
8285}
8386
@@ -86,46 +89,46 @@ type DiffHunk struct {
8689 OldLines int
8790 NewStart int
8891 NewLines int
89- Header string
92+ Header string
9093 DiffDelta
9194}
9295
93- func newDiffHunk (delta * C.git_diff_delta , hunk * C.git_diff_hunk ) * DiffHunk {
96+ func newDiffHunkFromC (delta * C.git_diff_delta , hunk * C.git_diff_hunk ) * DiffHunk {
9497 return & DiffHunk {
95- OldStart : int (hunk .old_start ),
96- OldLines : int (hunk .old_lines ),
97- NewStart : int (hunk .new_start ),
98- NewLines : int (hunk .new_lines ),
99- Header : C .GoStringN (& hunk .header [0 ], C .int (hunk .header_len )),
100- DiffDelta : * newDiffDelta (delta ),
98+ OldStart : int (hunk .old_start ),
99+ OldLines : int (hunk .old_lines ),
100+ NewStart : int (hunk .new_start ),
101+ NewLines : int (hunk .new_lines ),
102+ Header : C .GoStringN (& hunk .header [0 ], C .int (hunk .header_len )),
103+ DiffDelta : * newDiffDeltaFromC (delta ),
101104 }
102105}
103106
104107type DiffLine struct {
105- Origin DiffLineType
108+ Origin DiffLineType
106109 OldLineno int
107110 NewLineno int
108- NumLines int
109- Content string
111+ NumLines int
112+ Content string
110113 DiffHunk
111114}
112115
113- func newDiffLine (delta * C.git_diff_delta , hunk * C.git_diff_hunk , line * C.git_diff_line ) * DiffLine {
116+ func newDiffLineFromC (delta * C.git_diff_delta , hunk * C.git_diff_hunk , line * C.git_diff_line ) * DiffLine {
114117 return & DiffLine {
115- Origin : DiffLineType (line .origin ),
118+ Origin : DiffLineType (line .origin ),
116119 OldLineno : int (line .old_lineno ),
117120 NewLineno : int (line .new_lineno ),
118- NumLines : int (line .num_lines ),
119- Content : C .GoStringN (line .content , C .int (line .content_len )),
120- DiffHunk : * newDiffHunk (delta , hunk ),
121+ NumLines : int (line .num_lines ),
122+ Content : C .GoStringN (line .content , C .int (line .content_len )),
123+ DiffHunk : * newDiffHunkFromC (delta , hunk ),
121124 }
122125}
123126
124127type Diff struct {
125128 ptr * C.git_diff
126129}
127130
128- func newDiff (ptr * C.git_diff ) * Diff {
131+ func newDiffFromC (ptr * C.git_diff ) * Diff {
129132 if ptr == nil {
130133 return nil
131134 }
@@ -138,100 +141,165 @@ func newDiff(ptr *C.git_diff) *Diff {
138141 return diff
139142}
140143
141- func (diff * Diff ) Free () {
144+ func (diff * Diff ) Free () error {
145+ if diff .ptr != nil {
146+ return ErrInvalid
147+ }
142148 runtime .SetFinalizer (diff , nil )
143149 C .git_diff_free (diff .ptr )
150+ return nil
144151}
145152
146- func ( diff * Diff ) forEachFileWrap ( ch chan * DiffDelta ) {
147- C . _go_git_diff_foreach ( diff . ptr , 1 , 0 , 0 , unsafe . Pointer ( & ch ))
148- close ( ch )
153+ type diffForEachFileData struct {
154+ Callback DiffForEachFileCallback
155+ Error error
149156}
150157
151- func (diff * Diff ) ForEachFile () chan * DiffDelta {
152- ch := make (chan * DiffDelta , 0 )
153- go diff .forEachFileWrap (ch )
154- return ch
158+ func (diff * Diff ) ForEachFile (cb DiffForEachFileCallback ) error {
159+ if diff .ptr != nil {
160+ return ErrInvalid
161+ }
162+
163+ data := & diffForEachFileData {
164+ Callback : cb ,
165+ }
166+ ecode := C ._go_git_diff_foreach (diff .ptr , 1 , 0 , 0 , unsafe .Pointer (& data ))
167+ if ecode < 0 {
168+ return data .Error
169+ }
170+ return nil
155171}
156172
157173//export diffForEachFileCb
158174func diffForEachFileCb (delta * C.git_diff_delta , progress C.float , payload unsafe.Pointer ) int {
159- ch := * ( * chan * DiffDelta ) (payload )
175+ data := * diffForEachFileData (payload )
160176
161- select {
162- case ch <- newDiffDelta ( delta ):
163- case <- ch :
177+ err := data . Callback ( newDiffDeltaFromC ( delta ))
178+ if err != nil {
179+ data . Error = err
164180 return - 1
165181 }
166182
167183 return 0
168184}
169185
170- func ( diff * Diff ) forEachHunkWrap ( ch chan * DiffHunk ) {
171- C . _go_git_diff_foreach ( diff . ptr , 0 , 1 , 0 , unsafe . Pointer ( & ch ))
172- close ( ch )
186+ type diffForEachHunkData struct {
187+ Callback DiffForEachHunkCallback
188+ Error error
173189}
174190
175- func (diff * Diff ) ForEachHunk () chan * DiffHunk {
176- ch := make (chan * DiffHunk , 0 )
177- go diff .forEachHunkWrap (ch )
178- return ch
191+ type DiffForEachHunkCallback func (* DiffHunk ) error
192+
193+ func (diff * Diff ) ForEachHunk (cb DiffForEachHunkCallback ) error {
194+ if diff .ptr != nil {
195+ return ErrInvalid
196+ }
197+ data := & diffForEachHunkData {
198+ Callback : cb ,
199+ }
200+ ecode := C ._go_git_diff_foreach (diff .ptr , 0 , 1 , 0 , unsafe .Pointer (data ))
201+ if ecode < 0 {
202+ return data .Error
203+ }
204+ return nil
179205}
180206
181207//export diffForEachHunkCb
182208func diffForEachHunkCb (delta * C.git_diff_delta , hunk * C.git_diff_hunk , payload unsafe.Pointer ) int {
183- ch := * ( * chan * DiffHunk ) (payload )
209+ data := * diffForEachHunkData (payload )
184210
185- select {
186- case ch <- newDiffHunk ( delta , hunk ):
187- case <- ch :
211+ err := data . Callback ( newDiffHunkFromC ( delta , hunk ))
212+ if err < 0 {
213+ data . Error = err
188214 return - 1
189215 }
190216
191217 return 0
192218}
193219
194- func ( diff * Diff ) forEachLineWrap ( ch chan * DiffLine ) {
195- C . _go_git_diff_foreach ( diff . ptr , 0 , 0 , 1 , unsafe . Pointer ( & ch ))
196- close ( ch )
220+ type diffForEachLineData struct {
221+ Callback DiffForEachLineCallback
222+ Error error
197223}
198224
199- func (diff * Diff ) ForEachLine () chan * DiffLine {
200- ch := make (chan * DiffLine , 0 )
201- go diff .forEachLineWrap (ch )
202- return ch
225+ type DiffForEachLineCallback func (* DiffLine ) error
226+
227+ func (diff * Diff ) ForEachLine (cb DiffForEachLineCallback ) error {
228+ if diff .ptr != nil {
229+ return ErrInvalid
230+ }
231+
232+ data := & diffForEachLineData {
233+ Callback : cb ,
234+ }
235+
236+ ecode := C ._go_git_diff_foreach (diff .ptr , 0 , 0 , 1 , unsafe .Pointer (data ))
237+ if ecode < 0 {
238+ return data .Error
239+ }
240+ return nil
203241}
204242
205243//export diffForEachLineCb
206244func diffForEachLineCb (delta * C.git_diff_delta , hunk * C.git_diff_hunk , line * C.git_diff_line , payload unsafe.Pointer ) int {
207- ch := * (* chan * DiffLine )(payload )
208245
209- select {
210- case ch <- newDiffLine (delta , hunk , line ):
211- case <- ch :
246+ data := * diffForEachLineData (payload )
247+
248+ err := data .Callback (newDiffLineFromC (delta , hunk , line ))
249+ if err != nil {
250+ data .Error = err
212251 return - 1
213252 }
214253
215254 return 0
216255}
217256
218- func (diff * Diff ) NumDeltas () int {
219- return int (C .git_diff_num_deltas (diff .ptr ))
257+ func (diff * Diff ) NumDeltas () (int , error ) {
258+ if diff .ptr != nil {
259+ return - 1 , ErrInvalid
260+ }
261+ return int (C .git_diff_num_deltas (diff .ptr )), nil
220262}
221263
222- func (diff * Diff ) GetDelta (index int ) * DiffDelta {
264+ func (diff * Diff ) GetDelta (index int ) (* DiffDelta , error ) {
265+ if diff .ptr != nil {
266+ return nil , ErrInvalid
267+ }
223268 ptr := C .git_diff_get_delta (diff .ptr , C .size_t (index ))
224269 if ptr == nil {
225270 return nil
226271 }
227272
228- return newDiffDelta (ptr )
273+ return newDiffDeltaFromC (ptr ), nil
229274}
230275
231- func (diff * Diff ) Patch (deltaIndex int ) * Patch {
276+ func (diff * Diff ) Patch (deltaIndex int ) (* Patch , error ) {
277+ if diff .ptr != nil {
278+ return nil , ErrInvalid
279+ }
232280 var patchPtr * C.git_patch
233281
234- C .git_patch_from_diff (& patchPtr , diff .ptr , C .size_t (deltaIndex ))
282+ ecode := C .git_patch_from_diff (& patchPtr , diff .ptr , C .size_t (deltaIndex ))
283+ if ecode < 0 {
284+ return nil , MakeGitError (ecode )
285+ }
286+
287+ return newPatchFromC (patchPtr ), nil
288+ }
289+
290+ func (v * Repository ) DiffTreeToTree (oldTree , newTree * Tree ) * Diff {
291+ var diffPtr * C.git_diff
292+ var oldPtr , newPtr * C.git_tree
293+
294+ if oldTree != nil {
295+ oldPtr = oldTree .gitObject .ptr
296+ }
297+
298+ if newTree != nil {
299+ newPtr = newTree .gitObject .ptr
300+ }
301+
302+ C .git_diff_tree_to_tree (& diffPtr , v .ptr , oldPtr , newPtr , nil )
235303
236- return newPatch ( patchPtr )
304+ return newDiff ( diffPtr )
237305}
0 commit comments