Skip to content

Commit db17135

Browse files
committed
Export PatchFromBuffers function.
This change also factor out diffOptionsToC function to remove duplicated code.
1 parent 520a042 commit db17135

File tree

2 files changed

+59
-45
lines changed

2 files changed

+59
-45
lines changed

diff.go

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -459,29 +459,15 @@ func diffNotifyCb(_diff_so_far unsafe.Pointer, delta_to_add *C.git_diff_delta, m
459459
return 0
460460
}
461461

462-
func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (*Diff, error) {
463-
var diffPtr *C.git_diff
464-
var oldPtr, newPtr *C.git_tree
465-
466-
if oldTree != nil {
467-
oldPtr = oldTree.cast_ptr
468-
}
469-
470-
if newTree != nil {
471-
newPtr = newTree.cast_ptr
472-
}
473-
462+
func diffOptionsToC(opts *DiffOptions) (copts *C.git_diff_options, notifyData *diffNotifyData) {
474463
cpathspec := C.git_strarray{}
475-
var copts *C.git_diff_options
476-
var notifyData *diffNotifyData
477464
if opts != nil {
478465
notifyData = &diffNotifyData{
479466
Callback: opts.NotifyCallback,
480467
}
481468
if opts.Pathspec != nil {
482469
cpathspec.count = C.size_t(len(opts.Pathspec))
483470
cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
484-
defer freeStrarray(&cpathspec)
485471
}
486472

487473
copts = &C.git_diff_options{
@@ -500,6 +486,30 @@ func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (
500486
copts.notify_payload = unsafe.Pointer(notifyData)
501487
}
502488
}
489+
return
490+
}
491+
492+
func freeDiffOptions(copts *C.git_diff_options) {
493+
if copts != nil {
494+
cpathspec := copts.pathspec
495+
freeStrarray(&cpathspec)
496+
}
497+
}
498+
499+
func (v *Repository) DiffTreeToTree(oldTree, newTree *Tree, opts *DiffOptions) (*Diff, error) {
500+
var diffPtr *C.git_diff
501+
var oldPtr, newPtr *C.git_tree
502+
503+
if oldTree != nil {
504+
oldPtr = oldTree.cast_ptr
505+
}
506+
507+
if newTree != nil {
508+
newPtr = newTree.cast_ptr
509+
}
510+
511+
copts, notifyData := diffOptionsToC(opts)
512+
defer freeDiffOptions(copts)
503513

504514
runtime.LockOSThread()
505515
defer runtime.UnlockOSThread()
@@ -523,35 +533,8 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff,
523533
oldPtr = oldTree.cast_ptr
524534
}
525535

526-
cpathspec := C.git_strarray{}
527-
var copts *C.git_diff_options
528-
var notifyData *diffNotifyData
529-
if opts != nil {
530-
notifyData = &diffNotifyData{
531-
Callback: opts.NotifyCallback,
532-
}
533-
if opts.Pathspec != nil {
534-
cpathspec.count = C.size_t(len(opts.Pathspec))
535-
cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
536-
defer freeStrarray(&cpathspec)
537-
}
538-
539-
copts = &C.git_diff_options{
540-
version: C.GIT_DIFF_OPTIONS_VERSION,
541-
flags: C.uint32_t(opts.Flags),
542-
ignore_submodules: C.git_submodule_ignore_t(opts.IgnoreSubmodules),
543-
pathspec: cpathspec,
544-
context_lines: C.uint32_t(opts.ContextLines),
545-
interhunk_lines: C.uint32_t(opts.InterhunkLines),
546-
id_abbrev: C.uint16_t(opts.IdAbbrev),
547-
max_size: C.git_off_t(opts.MaxSize),
548-
}
549-
550-
if opts.NotifyCallback != nil {
551-
C._go_git_setup_diff_notify_callbacks(copts)
552-
copts.notify_payload = unsafe.Pointer(notifyData)
553-
}
554-
}
536+
copts, notifyData := diffOptionsToC(opts)
537+
defer freeDiffOptions(copts)
555538

556539
runtime.LockOSThread()
557540
defer runtime.UnlockOSThread()
@@ -565,5 +548,4 @@ func (v *Repository) DiffTreeToWorkdir(oldTree *Tree, opts *DiffOptions) (*Diff,
565548
return notifyData.Diff, nil
566549
}
567550
return newDiffFromC(diffPtr), nil
568-
569551
}

patch.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package git
66
import "C"
77
import (
88
"runtime"
9+
"unsafe"
910
)
1011

1112
type Patch struct {
@@ -50,3 +51,34 @@ func (patch *Patch) String() (string, error) {
5051
}
5152
return C.GoString(buf.ptr), nil
5253
}
54+
55+
func toPointer(data []byte) (ptr unsafe.Pointer) {
56+
if len(data) > 0 {
57+
ptr = unsafe.Pointer(&data[0])
58+
} else {
59+
ptr = unsafe.Pointer(nil)
60+
}
61+
return
62+
}
63+
64+
func (v *Repository) PatchFromBuffers(oldPath, newPath string, oldBuf, newBuf []byte, opts *DiffOptions) (*Patch, error) {
65+
var patchPtr *C.git_patch
66+
67+
oldPtr := toPointer(oldBuf)
68+
newPtr := (*C.char)(toPointer(newBuf))
69+
70+
cOldPath := C.CString(oldPath)
71+
defer C.free(unsafe.Pointer(cOldPath))
72+
73+
cNewPath := C.CString(newPath)
74+
defer C.free(unsafe.Pointer(cNewPath))
75+
76+
copts, _ := diffOptionsToC(opts)
77+
defer freeDiffOptions(copts)
78+
79+
ecode := C.git_patch_from_buffers(&patchPtr, oldPtr, C.size_t(len(oldBuf)), cOldPath, newPtr, C.size_t(len(newBuf)), cNewPath, copts)
80+
if ecode < 0 {
81+
return nil, MakeGitError(ecode)
82+
}
83+
return newPatchFromC(patchPtr), nil
84+
}

0 commit comments

Comments
 (0)