@@ -127,31 +127,37 @@ func diffLineFromC(line *C.git_diff_line) DiffLine {
127127}
128128
129129type Diff struct {
130- ptr * C.git_diff
130+ ptr * C.git_diff
131+ repo * Repository
131132}
132133
133134func (diff * Diff ) NumDeltas () (int , error ) {
134135 if diff .ptr == nil {
135136 return - 1 , ErrInvalid
136137 }
137- return int (C .git_diff_num_deltas (diff .ptr )), nil
138+ ret := int (C .git_diff_num_deltas (diff .ptr ))
139+ runtime .KeepAlive (diff )
140+ return ret , nil
138141}
139142
140143func (diff * Diff ) GetDelta (index int ) (DiffDelta , error ) {
141144 if diff .ptr == nil {
142145 return DiffDelta {}, ErrInvalid
143146 }
144147 ptr := C .git_diff_get_delta (diff .ptr , C .size_t (index ))
145- return diffDeltaFromC (ptr ), nil
148+ ret := diffDeltaFromC (ptr )
149+ runtime .KeepAlive (diff )
150+ return ret , nil
146151}
147152
148- func newDiffFromC (ptr * C.git_diff ) * Diff {
153+ func newDiffFromC (ptr * C.git_diff , repo * Repository ) * Diff {
149154 if ptr == nil {
150155 return nil
151156 }
152157
153158 diff := & Diff {
154- ptr : ptr ,
159+ ptr : ptr ,
160+ repo : repo ,
155161 }
156162
157163 runtime .SetFinalizer (diff , (* Diff ).Free )
@@ -187,6 +193,7 @@ func (diff *Diff) FindSimilar(opts *DiffFindOptions) error {
187193 defer runtime .UnlockOSThread ()
188194
189195 ecode := C .git_diff_find_similar (diff .ptr , copts )
196+ runtime .KeepAlive (diff )
190197 if ecode < 0 {
191198 return MakeGitError (ecode )
192199 }
@@ -209,15 +216,21 @@ func (stats *DiffStats) Free() error {
209216}
210217
211218func (stats * DiffStats ) Insertions () int {
212- return int (C .git_diff_stats_insertions (stats .ptr ))
219+ ret := int (C .git_diff_stats_insertions (stats .ptr ))
220+ runtime .KeepAlive (stats )
221+ return ret
213222}
214223
215224func (stats * DiffStats ) Deletions () int {
216- return int (C .git_diff_stats_deletions (stats .ptr ))
225+ ret := int (C .git_diff_stats_deletions (stats .ptr ))
226+ runtime .KeepAlive (stats )
227+ return ret
217228}
218229
219230func (stats * DiffStats ) FilesChanged () int {
220- return int (C .git_diff_stats_files_changed (stats .ptr ))
231+ ret := int (C .git_diff_stats_files_changed (stats .ptr ))
232+ runtime .KeepAlive (stats )
233+ return ret
221234}
222235
223236type DiffStatsFormat int
@@ -240,6 +253,7 @@ func (stats *DiffStats) String(format DiffStatsFormat,
240253
241254 ret := C .git_diff_stats_to_buf (& buf ,
242255 stats .ptr , C .git_diff_stats_format_t (format ), C .size_t (width ))
256+ runtime .KeepAlive (stats )
243257 if ret < 0 {
244258 return "" , MakeGitError (ret )
245259 }
@@ -253,7 +267,9 @@ func (diff *Diff) Stats() (*DiffStats, error) {
253267 runtime .LockOSThread ()
254268 defer runtime .UnlockOSThread ()
255269
256- if ecode := C .git_diff_get_stats (& stats .ptr , diff .ptr ); ecode < 0 {
270+ ecode := C .git_diff_get_stats (& stats .ptr , diff .ptr )
271+ runtime .KeepAlive (diff )
272+ if ecode < 0 {
257273 return nil , MakeGitError (ecode )
258274 }
259275 runtime .SetFinalizer (stats , (* DiffStats ).Free )
@@ -301,6 +317,7 @@ func (diff *Diff) ForEach(cbFile DiffForEachFileCallback, detail DiffDetail) err
301317 defer pointerHandles .Untrack (handle )
302318
303319 ecode := C ._go_git_diff_foreach (diff .ptr , 1 , intHunks , intLines , handle )
320+ runtime .KeepAlive (diff )
304321 if ecode < 0 {
305322 return data .Error
306323 }
@@ -380,6 +397,7 @@ func (diff *Diff) Patch(deltaIndex int) (*Patch, error) {
380397 defer runtime .UnlockOSThread ()
381398
382399 ecode := C .git_patch_from_diff (& patchPtr , diff .ptr , C .size_t (deltaIndex ))
400+ runtime .KeepAlive (diff )
383401 if ecode < 0 {
384402 return nil , MakeGitError (ecode )
385403 }
@@ -537,7 +555,7 @@ func diffNotifyCb(_diff_so_far unsafe.Pointer, delta_to_add *C.git_diff_delta, m
537555
538556 if data != nil {
539557 if data .Diff == nil {
540- data .Diff = newDiffFromC (diff_so_far )
558+ data .Diff = newDiffFromC (diff_so_far , nil )
541559 }
542560
543561 err := data .Callback (data .Diff , diffDeltaFromC (delta_to_add ), C .GoString (matched_pathspec ))
@@ -618,14 +636,16 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (
618636 defer runtime .UnlockOSThread ()
619637
620638 ecode := C .git_diff_tree_to_tree (& diffPtr , v .ptr , oldPtr , newPtr , copts )
639+ runtime .KeepAlive (oldTree )
640+ runtime .KeepAlive (newTree )
621641 if ecode < 0 {
622642 return nil , MakeGitError (ecode )
623643 }
624644
625645 if notifyData != nil && notifyData .Diff != nil {
626646 return notifyData .Diff , nil
627647 }
628- return newDiffFromC (diffPtr ), nil
648+ return newDiffFromC (diffPtr , v ), nil
629649}
630650
631651func (v * Repository ) DiffTreeToWorkdir (oldTree * Tree , opts * DiffOptions ) (* Diff , error ) {
@@ -643,14 +663,15 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff,
643663 defer runtime .UnlockOSThread ()
644664
645665 ecode := C .git_diff_tree_to_workdir (& diffPtr , v .ptr , oldPtr , copts )
666+ runtime .KeepAlive (oldTree )
646667 if ecode < 0 {
647668 return nil , MakeGitError (ecode )
648669 }
649670
650671 if notifyData != nil && notifyData .Diff != nil {
651672 return notifyData .Diff , nil
652673 }
653- return newDiffFromC (diffPtr ), nil
674+ return newDiffFromC (diffPtr , v ), nil
654675}
655676
656677func (v * Repository ) DiffTreeToIndex (oldTree * Tree , index * Index , opts * DiffOptions ) (* Diff , error ) {
@@ -673,14 +694,16 @@ func (v *Repository) DiffTreeToIndex(oldTree *Tree, index *Index, opts *DiffOpti
673694 defer runtime .UnlockOSThread ()
674695
675696 ecode := C .git_diff_tree_to_index (& diffPtr , v .ptr , oldPtr , indexPtr , copts )
697+ runtime .KeepAlive (oldTree )
698+ runtime .KeepAlive (index )
676699 if ecode < 0 {
677700 return nil , MakeGitError (ecode )
678701 }
679702
680703 if notifyData != nil && notifyData .Diff != nil {
681704 return notifyData .Diff , nil
682705 }
683- return newDiffFromC (diffPtr ), nil
706+ return newDiffFromC (diffPtr , v ), nil
684707}
685708
686709func (v * Repository ) DiffTreeToWorkdirWithIndex (oldTree * Tree , opts * DiffOptions ) (* Diff , error ) {
@@ -698,14 +721,15 @@ func (v *Repository) DiffTreeToWorkdirWithIndex(oldTree *Tree, opts *DiffOptions
698721 defer runtime .UnlockOSThread ()
699722
700723 ecode := C .git_diff_tree_to_workdir_with_index (& diffPtr , v .ptr , oldPtr , copts )
724+ runtime .KeepAlive (oldTree )
701725 if ecode < 0 {
702726 return nil , MakeGitError (ecode )
703727 }
704728
705729 if notifyData != nil && notifyData .Diff != nil {
706730 return notifyData .Diff , nil
707731 }
708- return newDiffFromC (diffPtr ), nil
732+ return newDiffFromC (diffPtr , v ), nil
709733}
710734
711735func (v * Repository ) DiffIndexToWorkdir (index * Index , opts * DiffOptions ) (* Diff , error ) {
@@ -723,14 +747,15 @@ func (v *Repository) DiffIndexToWorkdir(index *Index, opts *DiffOptions) (*Diff,
723747 defer runtime .UnlockOSThread ()
724748
725749 ecode := C .git_diff_index_to_workdir (& diffPtr , v .ptr , indexPtr , copts )
750+ runtime .KeepAlive (index )
726751 if ecode < 0 {
727752 return nil , MakeGitError (ecode )
728753 }
729754
730755 if notifyData != nil && notifyData .Diff != nil {
731756 return notifyData .Diff , nil
732757 }
733- return newDiffFromC (diffPtr ), nil
758+ return newDiffFromC (diffPtr , v ), nil
734759}
735760
736761// DiffBlobs performs a diff between two arbitrary blobs. You can pass
@@ -773,6 +798,8 @@ func DiffBlobs(oldBlob *Blob, oldAsPath string, newBlob *Blob, newAsPath string,
773798 defer runtime .UnlockOSThread ()
774799
775800 ecode := C ._go_git_diff_blobs (oldBlobPtr , oldBlobPath , newBlobPtr , newBlobPath , copts , 1 , intHunks , intLines , handle )
801+ runtime .KeepAlive (oldBlob )
802+ runtime .KeepAlive (newBlob )
776803 if ecode < 0 {
777804 return MakeGitError (ecode )
778805 }
0 commit comments